/**
* @file model.cpp
*
* Copyright (c) Huawei Technologies Co., Ltd. 2019-2020. All Rights reserved.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/

#include "acl/acl_mdl.h"
#include <vector>
#include <mutex>
#include <string>
#include <queue>
#include "securec.h"
#include "acl/acl_base.h"
#include "executor/ge_executor.h"
#include "common/ge_inner_error_codes.h"
#include "common/log_inner.h"
#include "runtime/stream.h"
#include "runtime/mem.h"
#include "runtime/rt_model.h"
#include "runtime/rts/rts_model.h"
#include "runtime/rts/rts_stream.h"
#include "graph/tensor.h"
#include "graph/types.h"
#include "exe_graph/runtime/tensor.h"
#include "exe_graph/runtime/shape.h"
#include "model_desc_internal.h"
#include "error_codes_inner.h"
#include "toolchain/profiling_manager.h"
#include "toolchain/resource_statistics.h"
#include "framework/common/ge_types.h"
#include "framework/runtime/model_v2_executor.h"
#include "framework/runtime/gert_api.h"
#include "framework/runtime/subscriber/global_profiler.h"
#include "utils/math_utils.h"
#include "utils/string_utils.h"
#include "model_config.h"
#include "acl_resource_manager.h"
#include "graph/ge_local_context.h"
#include "graph/ge_context.h"
#include "graph/def_types.h"
#include "utils/math_utils.h"

namespace {
constexpr size_t MIN_OUTPUT_SHAPE_INFO_SIZE = 2U;
constexpr size_t MAX_OUTPUT_SHAPE_INFO_SIZE = MIN_OUTPUT_SHAPE_INFO_SIZE + static_cast<size_t>(ACL_MAX_DIM_CNT);
constexpr size_t DYNAMIC_BATCH_SIZE = 1U;
constexpr size_t DYNAMIC_HW_SIZE = 2U;
constexpr size_t TENSOR_NAME_ATTR_NUM = 5U;
constexpr int32_t DEFAULT_SYNC_TIMEOUT = -1;
constexpr uint16_t kStartTag = 0U;
constexpr uint16_t kEndTag = 1U;
constexpr const char_t *TENSOR_NAME_PREFIX = "acl";
constexpr const char_t *TENSOR_INPUT_STR = "input";
constexpr const char_t *TENSOR_OUTPUT_STR = "output";
constexpr const char_t *MODEL_ID_STR = "modelId";
constexpr const char_t *OPTION_EXEC_REUSE_ZERO_COPY_MEMORY = "ge.exec.reuseZeroCopyMemory";

std::mutex aclmdlGetOpAttrMutex;

enum class DimsType : std::uint8_t {
    DIMS_TYPE_V1 = 0,
    DIMS_TYPE_V2
};

enum class TensorType : std::uint8_t {
    INPUT_TENSOR_TYPE = 0,
    OUTPUT_TENSOR_TYPE
};
}

aclmdlDesc *aclmdlCreateDesc()
{
    ACL_ADD_APPLY_TOTAL_COUNT(acl::ACL_STATISTICS_CREATE_DESTROY_DESC);
    ACL_ADD_APPLY_SUCCESS_COUNT(acl::ACL_STATISTICS_CREATE_DESTROY_DESC);
    return new(std::nothrow) aclmdlDesc();
}

aclError aclmdlDestroyDesc(aclmdlDesc *modelDesc)
{
    ACL_ADD_RELEASE_TOTAL_COUNT(acl::ACL_STATISTICS_CREATE_DESTROY_DESC);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelDesc);
    ACL_DELETE_AND_SET_NULL(modelDesc);
    ACL_ADD_RELEASE_SUCCESS_COUNT(acl::ACL_STATISTICS_CREATE_DESTROY_DESC);
    return ACL_SUCCESS;
}

namespace acl {
static aclError ParseBatchInfo(aclmdlDesc * const modelDesc, const int32_t dynamicType,
    const std::vector<std::vector<int64_t>> &batchInfo)
{
    const uint32_t modelId = modelDesc->modelId;
    if (dynamicType == static_cast<int32_t>(ge::DYNAMIC_DIMS)) { // dynamic dims, size can be [1, 4]
        const size_t dimCount = batchInfo[0U].size();
        for (size_t i = 0U; i < batchInfo.size(); ++i) {
            if (batchInfo[i].size() != dimCount) {
                ACL_LOG_INNER_ERROR("[Check][Size]Get dynamic model info invalid, model id[%u], one dim count is %zu "
                    "while another is %zu", modelId, dimCount, batchInfo[i].size());
                modelDesc->dynamicDims.clear();
                return ACL_ERROR_GE_FAILURE;
            }
            std::vector<uint64_t> oneDims;
            for (size_t j = 0U; j < dimCount; ++j) {
                oneDims.push_back(static_cast<uint64_t>(batchInfo[i][j]));
            }
            modelDesc->dynamicDims.push_back(oneDims);
        }
    } else if (batchInfo[0U].size() == DYNAMIC_BATCH_SIZE) { // dynamic batch,size is 1
        for (size_t i = 0U; i < batchInfo.size(); ++i) {
            if (batchInfo[i].size() != DYNAMIC_BATCH_SIZE) {
                ACL_LOG_INNER_ERROR("[Check][Size]get dynamic model info invalid, model id[%u]", modelId);
                modelDesc->dynamicBatch.clear();
                return ACL_ERROR_GE_FAILURE;
            }
            modelDesc->dynamicBatch.push_back(static_cast<uint64_t>(batchInfo[i][0U]));
        }
    } else if (batchInfo[0U].size() == DYNAMIC_HW_SIZE) { // dynamic hw,size is 2
        for (size_t i = 0U; i < batchInfo.size(); ++i) {
            if (batchInfo[i].size() != DYNAMIC_HW_SIZE) { // dynamic hw,size is 2
                ACL_LOG_INNER_ERROR("[Check][Size]get dynamic model info invalid, model id[%u]", modelId);
                modelDesc->dynamicHW.clear();
                return ACL_ERROR_GE_FAILURE;
            }
            modelDesc->dynamicHW.push_back({static_cast<uint64_t>(batchInfo[i][0U]),
                                            static_cast<uint64_t>(batchInfo[i][1U])});
        }
    } else {
        ACL_LOG_INNER_ERROR("[Get][DynamicModel]get dynamic model info invalid, model id[%u]", modelId);
        return ACL_ERROR_GE_FAILURE;
    }

    return ACL_SUCCESS;
}

static aclError GetDynamicTensorInfoHelp(aclmdlDesc * const modelDesc, const int32_t dynamicType,
    const std::vector<std::vector<int64_t>> &batchInfo)
{
    if (batchInfo.empty()) {
        ACL_LOG_INFO("model is not dynamic, batchInfo is empty, modelId[%u]", modelDesc->modelId);
        return ACL_SUCCESS;
    }

    ACL_LOG_INFO("model is dynamic, modelId[%u]", modelDesc->modelId);
    const aclError retVal = acl::ParseBatchInfo(modelDesc, dynamicType, batchInfo);
    if (retVal != ACL_SUCCESS) {
        ACL_LOG_INNER_ERROR("[Parse][BatchInfo]get model dynamic info failed, result[%d], model id[%u]",
            retVal, modelDesc->modelId);
        return retVal;
    }

    return ACL_SUCCESS;
}

static aclError GetDynamicTensorInfo(aclmdlDesc * const modelDesc)
{
    ACL_LOG_DEBUG("call ge interface executor.GetDynamicBatchInfo");
    std::vector<std::vector<int64_t>> batchInfo;
    ge::GeExecutor executor;
    const uint32_t modelId = modelDesc->modelId;
    int32_t dynamicType = static_cast<int32_t>(ge::FIXED);
    ge::Status ret = executor.GetDynamicBatchInfo(modelId, batchInfo, dynamicType);
    if (ret != ge::SUCCESS) {
        ACL_LOG_WARN("can not get dynamic model info, ge result[%u], model id[%u]", ret, modelId);
    }
    std::vector<std::string> userDesignateShapeOrder;
    ret = executor.GetUserDesignateShapeOrder(modelId, userDesignateShapeOrder);
    if (ret != ge::SUCCESS) {
        ACL_LOG_WARN("can not get user designate shape order, ge result[%u], model id[%u]", ret, modelId);
    }
    modelDesc->dataNameOrder = userDesignateShapeOrder;
    return GetDynamicTensorInfoHelp(modelDesc, dynamicType, batchInfo);
}

static aclError RuntimeV2GetDynamicTensorInfo(aclmdlDesc * const modelDesc, const gert::ModelDesc &geModelDesc)
{
    ACL_LOG_DEBUG("call ge interface executor.GetDynamicBatchInfo");
    std::vector<std::vector<int64_t>> batchInfo;
    const uint32_t modelId = modelDesc->modelId;
    int32_t dynamicType = static_cast<int32_t>(ge::FIXED);
    ge::Status ret = geModelDesc.GetDynamicBatchInfo(batchInfo, dynamicType);
    if (ret != ge::SUCCESS) {
        ACL_LOG_WARN("get dynamic model info failed, ge result[%u], model id[%u]", ret, modelId);
    }
    std::vector<std::string> userDesignateShapeOrder;
    ret = geModelDesc.GetUserDesignateShapeOrder(userDesignateShapeOrder);
    if (ret != ge::SUCCESS) {
        ACL_LOG_WARN("get user designate shape order failed, ge result[%u], model id[%u]", ret, modelId);
    }
    modelDesc->dataNameOrder = userDesignateShapeOrder;

    return GetDynamicTensorInfoHelp(modelDesc, dynamicType, batchInfo);
}

static aclError GetModelOutputShapeInfoHelp(aclmdlDesc * const modelDesc,
    std::vector<std::string> &geDynamicOutputShape)
{
    if (geDynamicOutputShape.empty()) {
        ACL_LOG_INFO("model is not dynamic, geDynamicOutputShape is empty, modelId[%u]", modelDesc->modelId);
        return ACL_SUCCESS;
    }

    std::vector<std::vector<int64_t>> &dynamicOutputShape = modelDesc->dynamicOutputShape;
    for (auto &it : geDynamicOutputShape) {
        int64_t val = 0;
        int64_t negativeFlag = 1;
        std::vector<int64_t> outputShape;
        // ge uses string like "0:0:1,3,224,224" to represent output shape info,
        // acl converts string like "0:0:1,3,224,224" to vector<int64_t>
        for (auto &strIt : it) {
            if ((strIt >= '0') && (strIt <= '9')) { // numeric character
                val = (val * 10) + static_cast<int64_t>(strIt - '0'); // character to number
            } else if (strIt == '-') { // '-' represents that dynamic model has static output
                negativeFlag = -1;
                ACL_LOG_DEBUG("dynamic model include static output");
            } else {
                val *= negativeFlag;
                outputShape.emplace_back(val);
                val = 0;
                negativeFlag = 1;
            }
        }
        val *= negativeFlag;
        outputShape.emplace_back(val); // last value
        dynamicOutputShape.emplace_back(outputShape);
    }

    return ACL_SUCCESS;
}

static aclError GetModelOutputShapeInfo(aclmdlDesc *const modelDesc)
{
    ACL_LOG_DEBUG("call ge interface executor.GetModelAttr");
    ge::GeExecutor executor;
    std::vector<std::string> geDynamicOutputShape;
    const uint32_t modelId = modelDesc->modelId;
    const ge::Status ret = executor.GetModelAttr(modelId, geDynamicOutputShape);
    if (ret != ge::SUCCESS) {
        ACL_LOG_CALL_ERROR("[Get][ModelAttr]get model attribute failed, ge result[%u], model id[%u]", ret, modelId);
        return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
    }
    return GetModelOutputShapeInfoHelp(modelDesc, geDynamicOutputShape);
}

static aclError RuntimeV2GetModelOutputShapeInfo(aclmdlDesc *const modelDesc, const gert::ModelDesc &geModeDesc)
{
    ACL_LOG_DEBUG("call ge interface executor.GetModelAttr");
    std::vector<std::string> geDynamicOutputShape;
    const uint32_t modelId = modelDesc->modelId;
    const ge::Status ret = geModeDesc.GetModelAttrs(geDynamicOutputShape);
    if (ret != ge::SUCCESS) {
        ACL_LOG_CALL_ERROR("[Get][ModelAttr]get model attribute failed, ge result[%u], model id[%u]", ret, modelId);
        return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
    }

    return GetModelOutputShapeInfoHelp(modelDesc, geDynamicOutputShape);
}

static aclError ModelLoadFromFileWithMem(const char_t *const modelPath, uint32_t *const modelId, void *const workPtr,
    const size_t workSize, void *const weightPtr, const size_t weightSize, const int32_t priority)
{
    ACL_LOG_INFO("start to execute ModelLoadFromFileWithMem, modelPath[%s], "
        "workSize[%zu], weightSize[%zu], priority[%d]", modelPath, workSize, weightSize, priority);

    ge::GeExecutor executor;
    uint32_t id = 0U;
    ge::ModelData data;
    const std::string path(modelPath);
    data.om_path = path;
    ACL_LOG_INFO("call ge interface executor.LoadDataFromFile, workSize[%zu], weightSize[%zu]",
        workSize, weightSize);
    ge::Status ret = executor.LoadDataFromFile(path, data);
    if (ret != ge::SUCCESS) {
        ACL_LOG_CALL_ERROR("[Model][FromFile]load model from file[%s] failed, ge result[%u]", modelPath, ret);
        ACL_DELETE_ARRAY(data.model_data);
        return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
    }
    data.priority = priority;
    ACL_LOG_INFO("call ge interface executor.LoadModelFromData, workSize[%zu], weightSize[%zu]",
        workSize, weightSize);
    ret = executor.LoadModelFromData(id, data, workPtr, workSize, weightPtr, weightSize);
    if (ret != ge::SUCCESS) {
        ACL_LOG_CALL_ERROR("[Model][FromData]load model from data failed, ge result[%u]", ret);
        ACL_DELETE_ARRAY(data.model_data);
        return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
    }

    *modelId = id;
    ACL_DELETE_ARRAY(data.model_data);
    ACL_LOG_INFO("successfully execute ModelLoadFromFileWithMem, workSize[%zu], weightSize[%zu], modelId[%u]",
        workSize, weightSize, *modelId);
    return ACL_SUCCESS;
}

static aclError RuntimeV2ModelLoadCommon(ge::ModelData &modelData, uint32_t *const modelId,
    const void *const weightPtr, const size_t weightSize, const std::shared_ptr<gert::RtSession> &rtSessionExternal)
{
    ACL_LOG_INFO("call ge interface gert::LoadExecutorFromModelData, weightSize[%zu]", weightSize);
    ge::graphStatus ret = ge::GRAPH_SUCCESS;
    std::unique_ptr<gert::ModelV2Executor> executor;
    if (rtSessionExternal == nullptr) { // old process, tmp solution
        executor = gert::LoadExecutorFromModelData(modelData, ret);
    } else { // new process, delete old process after ge api ready
        executor = gert::LoadExecutorFromModelDataWithRtSession(modelData, rtSessionExternal.get(), ret);
    }
    if (ret != ge::GRAPH_SUCCESS) {
        ACL_LOG_CALL_ERROR("[Model][FromData]call gert::LoadExecutorFromModelDataWithMem load model from data failed, "
                           "ge result[%u]", ret);
        return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
    }
    ACL_REQUIRES_NOT_NULL(executor);
    // 4. load rt2.0 executor
    ACL_LOG_DEBUG("call ge interface executorV2.Load");
    auto rtSession = (rtSessionExternal != nullptr) ? rtSessionExternal :
            acl::AclResourceManager::GetInstance().CreateRtSession();
    ACL_REQUIRES_NOT_NULL(rtSession);
    rtStream_t rtStream = nullptr;
    ACL_REQUIRES_CALL_RTS_OK(
        rtStreamCreate(&rtStream, static_cast<int32_t>(RT_STREAM_PRIORITY_DEFAULT)), rtStreamCreate);

    gert::ModelExecuteArg exeArg;
    exeArg.stream = rtStream;
    ret = executor->Load(exeArg, gert::ModelLoadArg(rtSession.get(), {weightPtr, weightSize}));
    if (ret != ge::GRAPH_SUCCESS) {
        ACL_LOG_CALL_ERROR("[Model][FromData]call load executorV2 failed, ge result[%u]", ret);
        (void)rtStreamDestroy(static_cast<rtStream_t>(rtStream));
        return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
    }
    ret = rtStreamSynchronize(rtStream);
    if (ret != RT_ERROR_NONE) {
        ACL_LOG_CALL_ERROR("synchronize stream failed, runtime result = %d", static_cast<int32_t>(ret));
        (void)rtStreamDestroy(static_cast<rtStream_t>(rtStream));
        return ACL_GET_ERRCODE_RTS(ret);
    }
    (void)rtStreamDestroy(static_cast<rtStream_t>(rtStream));

    // 5. get model-id
    acl::AclResourceManager::GetInstance().AddExecutor(*modelId , std::move(executor), rtSession);
    return ACL_SUCCESS;
}

static aclError RuntimeV2ModelLoadFromFileWithMem(const char_t *const modelPath, uint32_t *const modelId,
                                                  void *const weightPtr, const size_t weightSize,
                                                  const int32_t priority,
                                                  const std::shared_ptr<gert::RtSession> &rtSessionExternal = nullptr)
{
    ACL_LOG_INFO("start to execute RuntimeV2ModelLoadFromFileWithMem, priority[%d], weightSize[%zu]",
                 priority, weightSize);

    // 1. load model data from file
    ge::ModelData modelData;
    modelData.om_path = modelPath;
    ge::graphStatus ret = ge::GRAPH_SUCCESS;
    ACL_LOG_INFO("call ge interface gert::LoadDataFromFile");
    ret = gert::LoadDataFromFile(modelPath, modelData);
    if (ret != ge::GRAPH_SUCCESS) {
        ACL_LOG_CALL_ERROR("[Load][Model]failed to load model from file by runtime2.0, ge errorCode is %u", ret);
        return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
    }
    std::shared_ptr<void> dataAuto;
    dataAuto.reset(modelData.model_data, [](const void * const p) { delete[] static_cast<const uint8_t *>(p); });
    // 2. config model data
    modelData.priority = priority;
    // 3. get rt2.0 executor
    ACL_REQUIRES_OK(RuntimeV2ModelLoadCommon(modelData, modelId, weightPtr, weightSize, rtSessionExternal));
    ACL_LOG_INFO("successfully execute RuntimeV2ModelLoadFromFileWithMem, modelSize[%lu], modelId[%u], weightSize[%zu]",
                 modelData.model_len, *modelId, weightSize);
    return ACL_SUCCESS;
}

static aclError ModelLoadFromMemWithMem(const void *const model, const size_t modelSize, const std::string &modelPath,
                                        uint32_t *const modelId,void *const workPtr, const size_t workSize,
                                        void *const weightPtr, const size_t weightSize, const char_t *const weightPath,
                                        const int32_t priority,
                                        const std::shared_ptr<gert::RtSession> &rtSessionExternal = nullptr)
{
    ACL_LOG_INFO("start to execute ModelLoadFromMemWithMem, workSize[%zu], weightSize[%zu], priority[%d]",
        workSize, weightSize, priority);
    if (modelSize == 0U) {
        ACL_LOG_INNER_ERROR("[Check][ModelSize]modelSize[%zu] is invalid, should not be zero", modelSize);
        return ACL_ERROR_INVALID_PARAM;
    }

    ge::GeExecutor geExecutor;
    uint32_t id = 0U;
    ge::ModelData modelData;
    modelData.model_data = const_cast<void *>(model);
    modelData.model_len = static_cast<uint64_t>(modelSize);
    modelData.priority = priority;
    modelData.om_path = modelPath;
    if (weightPath != nullptr) {
        modelData.weight_path = std::string(weightPath);
        ACL_LOG_INFO("Load weight path is [%s]", modelData.weight_path.c_str());
    }
    ACL_LOG_INFO("call ge interface executor.LoadModelFromData, modelSize[%zu], workSize[%zu], weightSize[%zu]",
        modelSize, workSize, weightSize);
    ge::Status ret = ge::SUCCESS;
    if (rtSessionExternal == nullptr) {
        ret = geExecutor.LoadModelFromData(id, modelData, workPtr, workSize, weightPtr, weightSize);
    } else {
        ge::ModelLoadArg loadArgs{};
        loadArgs.dev_ptr = workPtr;
        loadArgs.mem_size = workSize;
        loadArgs.weight_ptr = weightPtr;
        loadArgs.weight_size = weightSize;
        loadArgs.rt_session = rtSessionExternal.get();
        ret = geExecutor.LoadModelFromDataWithArgs(id, modelData, loadArgs);
    }
    if (ret != ge::SUCCESS) {
        ACL_LOG_CALL_ERROR("[Model][FromData]load model from data failed, ge result[%u]", ret);
        return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
    }

    *modelId = id;
    ACL_LOG_INFO("successfully execute ModelLoadFromMemWithMem, modelSize[%zu], workSize[%zu], "
        "weightSize[%zu], modelId[%u]", modelSize, workSize, weightSize, *modelId);
    return ACL_SUCCESS;
}

static aclError IsSupportRuntimeV2WithModelPath(const char *filePath, bool &isSupportRuntimeV2)
{
    if (!acl::AclResourceManager::GetInstance().IsRuntimeV2Enable(true)) {
        isSupportRuntimeV2 = false;
        return ACL_SUCCESS;
    }
    const auto ret = gert::IsDynamicModel(filePath, isSupportRuntimeV2);
    if (ret != ge::GRAPH_SUCCESS) {
        ACL_LOG_ERROR("[Check][Model] failed, modelPath is null, or file is invalid, ret[%u].", ret);
        return static_cast<aclError>(ret);
    }
    return ACL_SUCCESS;
}

    static aclError GetBundleNumAndOffset(const void *const model, const size_t modelSize,
                                          bool &isBundleOm, std::vector<std::pair<size_t, size_t>> &offsetAndSize)
    {
        isBundleOm = false;
        size_t currentOffset = 0U;
        if (modelSize < (sizeof(ge::ModelFileHeader) + sizeof(ge::ModelPartitionTable))) {
            ACL_LOG_ERROR("[Check][Param] Invalid model size, Model data size %zu must be greater than or equal to %zu.",
                          modelSize, sizeof(ge::ModelFileHeader));
            return ACL_ERROR_INVALID_PARAM;
        }
        const auto *fileHeader = ge::PtrToPtr<void, ge::ModelFileHeader>(model);
        if (fileHeader->modeltype != ge::MODEL_TYPE_BUNDLE_MODEL) {
          ACL_LOG_INFO("this is not bundle om");
          return ACL_SUCCESS;
        }
        currentOffset += sizeof(ge::ModelFileHeader);
        isBundleOm = true;
        const auto *partitionTable =
                ge::PtrToPtr<void, ge::ModelPartitionTable>(ge::ValueToPtr(ge::PtrToValue(model) + currentOffset));
        const size_t partitionTableSize = ge::SizeOfModelPartitionTable(*partitionTable);
        ACL_LOG_INFO("get offset %zu, partitionTableSize %zu", currentOffset, partitionTableSize);

        ACL_REQUIRES_OK(acl::CheckSizeTAddOverflow(currentOffset, partitionTableSize, currentOffset));
        ACL_REQUIRES_LE(currentOffset, modelSize);
        for (size_t i = 0; i < partitionTable->num; ++i) {
          ACL_LOG_INFO("get %zu om offset %zu, size %zu", i, currentOffset, partitionTable->partition[i].mem_size);
          offsetAndSize.emplace_back(currentOffset, partitionTable->partition[i].mem_size);
          ACL_REQUIRES_OK(acl::CheckSizeTAddOverflow(currentOffset,
                                                     partitionTable->partition[i].mem_size, currentOffset));
          ACL_REQUIRES_LE(currentOffset, modelSize);
        }
        return ACL_SUCCESS;
    }

    static aclError IsSupportRuntimeV2WithModelData(const void *const model, const size_t modelSize,
                                                    bool &isSupportRuntimeV2)
    {
      if (!acl::AclResourceManager::GetInstance().IsRuntimeV2Enable(true)) {
        isSupportRuntimeV2 = false;
        return ACL_SUCCESS;
      }
      ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(model);
      if (modelSize < sizeof(ge::ModelFileHeader)) {
        ACL_LOG_ERROR("[Check][Param] Invalid model size, Model data size %zu must be greater than or equal to %zu.",
                      modelSize, sizeof(ge::ModelFileHeader));
        return ACL_ERROR_INVALID_PARAM;
      }
      const auto *fileHeader = reinterpret_cast<const ge::ModelFileHeader *>(model);
      constexpr uint32_t kStaticOmFileModelNum = 1U;
      constexpr uint8_t kDynamicOmFlag = 1U;
      isSupportRuntimeV2 =
              ((fileHeader->version >= ge::MODEL_VERSION) &&
               ((fileHeader->model_num > kStaticOmFileModelNum) || (fileHeader->is_unknow_model == kDynamicOmFlag)));
      return ACL_SUCCESS;
    }

static aclError RuntimeV2ModelLoadFromMemWithMem(const void *const model, const size_t modelSize,
                                                 const std::string &modelPath,
                                                 uint32_t *const modelId, void *const weightPtr,
                                                 const size_t weightSize, const char_t *const weightPath,
                                                 const int32_t priority,
                                                 const std::shared_ptr<gert::RtSession> &rtSessionExternal = nullptr)
{
    ACL_LOG_INFO("start to execute RuntimeV2ModelLoadFromMemWithMem, modelSize[%zu], priority[%d], weightSize[%zu]",
                 modelSize, priority, weightSize);
    ACL_CHECK_WITH_INNER_MESSAGE_AND_RETURN(modelSize != 0U, ACL_ERROR_INVALID_PARAM,
        "[Check][ModelSize]modelSize[%zu] is invalid, should not be zero", modelSize);
    // 1. config model data
    ge::ModelData modelData;
    modelData.model_data = const_cast<void *>(model);
    modelData.model_len = static_cast<uint64_t>(modelSize);
    modelData.priority = priority;
    modelData.om_path = modelPath;
    if (weightPath != nullptr) {
        modelData.weight_path = std::string(weightPath);
        ACL_LOG_INFO("Load weight path is [%s]", modelData.weight_path.c_str());
    }

    // 2. get executorV2
    ACL_REQUIRES_OK(RuntimeV2ModelLoadCommon(modelData, modelId, weightPtr, weightSize, rtSessionExternal));
    ACL_LOG_INFO("successfully execute RuntimeV2ModelLoadFromMemWithMem, modelSize[%zu], modelId[%u], weightSize[%zu]",
                 modelSize, *modelId, weightSize);
    return ACL_SUCCESS;
}

static aclError ModelLoadFromFileWithQ(const char_t *const modelPath, uint32_t *const modelId,
    const uint32_t *const inputQ, const size_t inputQNum, const uint32_t *const outputQ,
    const size_t outputQNum, const int32_t priority)
{
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelPath);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelId);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(inputQ);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(outputQ);
    ACL_LOG_INFO("start to execute ModelLoadFromFileWithQ, modelPath[%s], inputQNum[%zu], "
        "outputQNum[%zu], priority[%d]", modelPath, inputQNum, outputQNum, priority);

    if ((inputQNum == 0U) || (outputQNum == 0U)) {
        ACL_LOG_INNER_ERROR("[Check][QNum]inputQNum[%zu] or outputQNum[%zu] is invalid, can't be zero",
            inputQNum, outputQNum);
        return ACL_ERROR_INVALID_PARAM;
    }

    ge::GeExecutor geExecutor;
    uint32_t id = 0U;
    ge::ModelData modelData;
    const std::string path(modelPath);
    ACL_LOG_INFO("call ge interface executor.LoadDataFromFile");
    ge::Status ret = geExecutor.LoadDataFromFile(path, modelData);
    if (ret != ge::SUCCESS) {
        ACL_LOG_CALL_ERROR("[Load][FromFile]load model from file[%s], ge result[%u], failed", modelPath, ret);
        ACL_DELETE_ARRAY(modelData.model_data);
        return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
    }
    modelData.priority = priority;
    const std::vector<uint32_t> inputQVec(inputQ, inputQ + inputQNum);
    const std::vector<uint32_t> outputQVec(outputQ, outputQ + outputQNum);

    ACL_LOG_INFO("call ge interface executor.LoadModelWithQ");
    ret = geExecutor.LoadModelWithQ(id, modelData, inputQVec, outputQVec);
    if (ret != ge::SUCCESS) {
        ACL_LOG_CALL_ERROR("[Load][WithQ]execute LoadModelWithQ failed, ge result[%u]", ret);
        ACL_DELETE_ARRAY(modelData.model_data);
        return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
    }

    *modelId = id;
    ACL_DELETE_ARRAY(modelData.model_data);

    ACL_LOG_INFO("successfully execute ModelLoadFromFileWithQ, modelPath[%s], inputQNum[%zu], outputQNum[%zu], "
        "modelId[%u]", modelPath, inputQNum, outputQNum, *modelId);
    return ACL_SUCCESS;
}

static aclError ModelLoadFromMemWithQ(const void *const model, const size_t modelSize, uint32_t *const modelId,
    const uint32_t *const inputQ, const size_t inputQNum, const uint32_t *const outputQ,
    const size_t outputQNum, const int32_t priority)
{
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(model);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelId);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(inputQ);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(outputQ);
    ACL_LOG_INFO("start to execute ModelLoadFromMemWithQ, modelSize[%zu], inputQNum[%zu], outputQNum[%zu], "
        "priority[%d]", modelSize, inputQNum, outputQNum, priority);

    if ((modelSize == 0U) || (inputQNum == 0U) || (outputQNum == 0U)) {
        ACL_LOG_INNER_ERROR("[Check][Params]modelSize[%zu] or inputQNum[%zu] or outputQNum[%zu] is invalid, "
            "can't be zero", modelSize, inputQNum, outputQNum);
        return ACL_ERROR_INVALID_PARAM;
    }

    ge::GeExecutor executor;
    uint32_t id = 0U;
    ge::ModelData data;

    data.model_data = const_cast<void *>(model);
    data.model_len = static_cast<uint64_t>(modelSize);
    data.priority = priority;

    const std::vector<uint32_t> inputQVec(inputQ, inputQ + inputQNum);
    const std::vector<uint32_t> outputQVec(outputQ, outputQ + outputQNum);

    ACL_LOG_INFO("call ge interface executor.LoadModelWithQ, modelSize[%zu]", modelSize);
    const ge::Status ret = executor.LoadModelWithQ(id, data, inputQVec, outputQVec);
    if (ret != ge::SUCCESS) {
        ACL_LOG_CALL_ERROR("[Load][WithQ]load model with Q, ge result[%u], failed", ret);
        return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
    }

    *modelId = id;
    ACL_LOG_INFO("successfully execute ModelLoadFromMemWithQ, modelSize[%zu], inputQNum[%zu], outputQNum[%zu], "
        "modelId[%u]", modelSize, inputQNum, outputQNum, *modelId);

    return ACL_SUCCESS;
}

static void SetInputData(const std::vector<AclModelTensor> &blobs,
    std::vector<ge::GeTensorDesc> &inputGeDesc, bool &isDynamic)
{
    for (size_t i = 0U; i < blobs.size(); ++i) {
        if (blobs[i].tensorDesc != nullptr) {
            isDynamic = true;
            break;
        }
    }
    if (isDynamic) {
        for (size_t i = 0U; i < blobs.size(); ++i) {
            if (blobs[i].tensorDesc != nullptr) {
                std::vector<int64_t> dims;
                ConvertSvecToVec(blobs[i].tensorDesc->dims, dims);
                const ge::GeShape shape(dims);
                ge::GeTensorDesc geTensorDescTmp(shape);
                geTensorDescTmp.SetOriginShape(shape);
                inputGeDesc.push_back(geTensorDescTmp);
            } else {
                const ge::GeTensorDesc geTensorDescTmp;
                inputGeDesc.push_back(geTensorDescTmp);
            }
        }
    }
    return;
}

static void WrapGeShape(gert::Shape &geShape,
    const ge::SmallVector<int64_t, static_cast<size_t>(ge::kDefaultMaxInputNum)> &dims)
{
    geShape.SetDimNum(dims.size());
    for (size_t i = 0U; i < dims.size(); ++i) {
        (void)geShape.SetDim(i, dims[i]);
    }
}

static void SetInputData(const std::vector<AclModelTensor> &blobs,
    std::vector<gert::Tensor> &inputTensor)
{
    for (size_t i = 0U; i < inputTensor.size(); ++i) {
        if (blobs[i].tensorDesc != nullptr) {
            WrapGeShape(inputTensor[i].MutableOriginShape(), blobs[i].tensorDesc->dims);
            WrapGeShape(inputTensor[i].MutableStorageShape(), blobs[i].tensorDesc->dims);
        }
    }
    return;
}

// runtime2.0 execute
static aclError RuntimeV2ModelExecute(const uint32_t modelId, const aclmdlDataset *const input,
    aclmdlDataset *const output, const bool isAsync, const aclrtStream stream)
{
    ACL_LOG_INFO("start to execute ModelExecute, modelId[%u]", modelId);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(input);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(output);

    auto const executor = acl::AclResourceManager::GetInstance().GetExecutor(modelId);
    if (executor == nullptr) {
        ACL_LOG_ERROR("input modelId[%u] is invalid, please make sure model has been loaed", modelId);
        return static_cast<aclError>(ACL_ERROR_GE_EXEC_MODEL_ID_INVALID);
    }

    const gert::ModelDesc &desc = executor->GetModelDesc();
    const size_t inputNum = desc.GetInputNum();
    ACL_LOG_INFO("get model input num %zu, input num %zu", inputNum, input->blobs.size());
    if (input->blobs.size() < inputNum) {
        ACL_LOG_ERROR("intput blobs %zu can not be smaller than intput desc size %zu",
            input->blobs.size(), inputNum);
        return static_cast<aclError>(ACL_ERROR_INVALID_PARAM);
    }

    std::vector<gert::Tensor> inputTensor(inputNum);
    std::vector<gert::Tensor> outputTensor(output->blobs.size());
    std::vector<gert::Tensor *> inputVec(inputNum);
    std::vector<gert::Tensor *> outputVec(output->blobs.size());
    for (size_t i = 0UL; i < inputNum; ++i) {
        const auto dataBuffer = input->blobs[i].dataBuf;
        if (dataBuffer == nullptr) {
            ACL_LOG_ERROR("[Check][dataBuffer]input dataset blobs is null, "
                "modelId[%d], index[%zu]", modelId, i);
            acl::AclErrorLogManager::ReportInputError(acl::INVALID_NULL_POINTER_MSG,
                std::vector<std::string>({"param"}),
                std::vector<std::string>({"dataBuffer"}));
            return ACL_ERROR_INVALID_PARAM;
        }
        inputTensor[i].MutableTensorData().SetPlacement(gert::kOnDeviceHbm);
        (void)inputTensor[i].MutableTensorData().SetAddr(dataBuffer->data, nullptr);
        inputTensor[i].MutableTensorData().SetSize(dataBuffer->length);
        inputTensor[i].MutableOriginShape() = desc.GetInputDesc(i)->GetOriginShape();
        inputTensor[i].MutableStorageShape() = desc.GetInputDesc(i)->GetStorageShape();
        inputVec[i] = &(inputTensor[i]);
    }

    SetInputData(input->blobs, inputTensor);
    ge::InputAippType type = ge::DATA_WITHOUT_AIPP;
    size_t aippIndex = 0U;
    for (size_t i = 0UL; i < inputNum; ++i) {
        (void)executor->GetAippType(static_cast<uint32_t>(i), type, aippIndex);
        if (type == ge::DATA_WITH_DYNAMIC_AIPP) {
            // dynamic aipp input no need to check range for compatibility
            continue;
        }
        if (!desc.GetInputDesc(i)->IsOriginShapeInRange(inputTensor[i].GetOriginShape())) {
            ACL_LOG_ERROR("[Check][InputShape] Input [%zu] shape out of shape range.", i);
            return ACL_ERROR_INVALID_PARAM;
        }
    }

    for (size_t i = 0UL; i < output->blobs.size(); ++i) {
        const auto dataBuffer = output->blobs[i].dataBuf;
        if (dataBuffer == nullptr) {
            ACL_LOG_ERROR("[Check][Databuffer]output dataset blobs is null, modelId[%d], index[%zu]",
                modelId, i);
            acl::AclErrorLogManager::ReportInputError(acl::INVALID_NULL_POINTER_MSG,
                std::vector<std::string>({"param"}),
                std::vector<std::string>({"dataBuffer"}));
            return ACL_ERROR_INVALID_PARAM;
        }
        if ((dataBuffer->data == nullptr) && (!isAsync)) {
            const size_t memSize = static_cast<size_t>(desc.GetOutputDesc(i)->GetSize());
            if (memSize > 0UL) {
                ACL_REQUIRES_CALL_RTS_OK(rtMalloc(reinterpret_cast<void **>(&dataBuffer->data), memSize, RT_MEMORY_HBM,
                    acl::ACL_MODE_ID_U16), rtMalloc);
                dataBuffer->length = memSize;
                ACL_LOG_DEBUG("ModelExecute, assign acl-malloced output addr to user-defined buffer, addr:[%p], "
                              "len:[%lu]", dataBuffer->data, dataBuffer->length);
            }
        }

        outputTensor[i].MutableTensorData().SetPlacement(gert::kOnDeviceHbm);
        (void)outputTensor[i].MutableTensorData().SetAddr(dataBuffer->data, nullptr);
        outputTensor[i].MutableTensorData().SetSize(dataBuffer->length);
        outputVec[i] = &(outputTensor[i]);
    }

    ge::Status ret = ge::GRAPH_SUCCESS;
    const auto index_id = executor->GetIterationNum();
    MsprofEvent event{};
    CANN_PROFILING_EVENT_START(modelId, index_id, gert::GeProfInfoType::kModelExecute, event);
    CANN_PROFILING_STEP_TRACE(modelId, index_id, kStartTag, stream);
    if (isAsync) {
        gert::ModelExecuteArg arg;
        arg.stream = stream;
        arg.external_allocator = acl::AclResourceManager::GetInstance().GetAllocators(arg.stream, false);
        ret = executor->Execute(arg, inputVec.data(), inputTensor.size(), outputVec.data(), outputTensor.size());
    } else {
        ret = executor->ExecuteSync(inputVec.data(), inputTensor.size(), outputVec.data(), outputTensor.size());
    }
    CANN_PROFILING_STEP_TRACE(modelId, index_id, kEndTag, stream);
    CANN_PROFILING_EVENT_END(modelId, index_id, gert::GeProfInfoType::kModelExecute, event);
    if (ret != ge::SUCCESS) {
        ACL_LOG_CALL_ERROR("[Exec][Model]Execute model failed, ge result[%u], modelId[%u]", ret, modelId);
        return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
    }
    for (size_t i = 0UL; i < output->blobs.size(); ++i) {
        if (output->blobs[i].tensorDesc != nullptr) {
            aclDestroyTensorDesc(output->blobs[i].tensorDesc);
        }
        output->blobs[i].tensorDesc = aclCreateTensorDesc(ACL_DT_UNDEFINED, 0, nullptr, ACL_FORMAT_UNDEFINED);
    }

    for (size_t i = 0UL; i < outputTensor.size(); ++i) {
        if (output->blobs[i].tensorDesc != nullptr) {
            output->blobs[i].tensorDesc->dims.clear();
            const ge::Format format = outputTensor[i].GetFormat().GetStorageFormat();
            const ge::DataType dataType = outputTensor[i].GetDataType();
            for (size_t idx = 0U; idx < outputTensor[i].MutableStorageShape().GetDimNum(); ++idx) {
                output->blobs[i].tensorDesc->dims.push_back(outputTensor[i].MutableStorageShape().GetDim(idx));
            }
            if (format != ge::FORMAT_RESERVED) {
                output->blobs[i].tensorDesc->format = static_cast<aclFormat>(format);
            }
            if (dataType != ge::DT_UNDEFINED) {
                output->blobs[i].tensorDesc->dataType = static_cast<aclDataType>(dataType);
            }
        }

        auto &dataBuffer = output->blobs[i].dataBuf;
        if ((dataBuffer->data == nullptr) && (!isAsync)) {
            ACL_REQUIRES_NOT_NULL(outputTensor[i].MutableTensorData().GetAddr());
            const auto outputSize = outputTensor[i].MutableTensorData().GetSize();
            ACL_REQUIRES_CALL_RTS_OK(rtMalloc(reinterpret_cast<void **>(&dataBuffer->data), outputSize,
                RT_MEMORY_HBM, acl::ACL_MODE_ID_U16), rtMalloc);
            ACL_REQUIRES_CALL_RTS_OK(rtMemcpy(dataBuffer->data, outputSize,
                outputTensor[i].MutableTensorData().GetAddr(), outputSize, RT_MEMCPY_DEVICE_TO_DEVICE), rtMemcpy);
            dataBuffer->length = outputSize;
            ACL_LOG_DEBUG("ModelExecute, assign acl-malloced output addr to user-defined buffer, addr:[%p], len:[%lu]",
                          dataBuffer->data, dataBuffer->length);
        }
    }

    ACL_LOG_INFO("successfully execute ModelExecute, modelId[%u]", modelId);
    return ACL_SUCCESS;
}

static aclError ModelExecute(const uint32_t modelId, const aclmdlDataset *const input,
    aclmdlDataset *const output, const bool basync, const aclrtStream stream)
{
    ACL_LOG_INFO("start to execute ModelExecute, modelId[%u]", modelId);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(input);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(output);

    ge::RunModelData inputData;
    inputData.timeout = 0U;
    inputData.timestamp = 0U;
    inputData.index = 0U;
    inputData.modelId = modelId;

    inputData.dynamic_batch_size = input->dynamicBatchSize;
    inputData.dynamic_image_height = input->dynamicResolutionHeight;
    inputData.dynamic_image_width = input->dynamicResolutionWidth;
    inputData.dynamic_dims = input->dynamicDims;
    ACL_LOG_DEBUG("ModelExecute dynamic param: batch_size[%lu], height[%lu], width[%lu], dim_num[%zu]",
                  input->dynamicBatchSize, input->dynamicResolutionHeight, input->dynamicResolutionWidth,
                  input->dynamicDims.size());
    inputData.blobs.resize(input->blobs.size());
    for (size_t i = 0UL; i < input->blobs.size(); ++i) {
        ge::DataBuffer &inputBuffer = inputData.blobs[i];
        const auto dataBuffer = input->blobs[i].dataBuf;
        if (dataBuffer == nullptr) {
            ACL_LOG_ERROR("[Check][dataBuffer]input dataset blobs is null, "
                "modelId[%d], index[%zu]", modelId, i);
            acl::AclErrorLogManager::ReportInputError(acl::INVALID_NULL_POINTER_MSG,
                std::vector<std::string>({"param"}),
                std::vector<std::string>({"dataBuffer"}));
            return ACL_ERROR_INVALID_PARAM;
        }
        inputBuffer.data = dataBuffer->data;
        inputBuffer.length = dataBuffer->length;
        inputBuffer.isDataSupportMemShare = false;
        inputBuffer.placement = ge::Placement::kPlacementDevice;
    }

    std::vector<ge::GeTensorDesc> inputGeDesc;
    bool dynamicFlag = false;
    SetInputData(input->blobs, inputGeDesc, dynamicFlag);

    ge::RunModelData outputData;
    outputData.modelId = modelId;

    std::vector<size_t> needMallocIndexes;
    outputData.blobs.resize(output->blobs.size());
    for (size_t i = 0UL; i < output->blobs.size(); ++i) {
        ge::DataBuffer &outputBuffer = outputData.blobs[i];
        const auto dataBuffer = output->blobs[i].dataBuf;
        if (dataBuffer == nullptr) {
            ACL_LOG_ERROR("[Check][Databuffer]output dataset blobs is null, modelId[%d], index[%zu]",
                modelId, i);
            acl::AclErrorLogManager::ReportInputError(acl::INVALID_NULL_POINTER_MSG,
                std::vector<std::string>({"param"}),
                std::vector<std::string>({"dataBuffer"}));
            return ACL_ERROR_INVALID_PARAM;
        }
        if (dataBuffer->data == nullptr) {
            needMallocIndexes.push_back(i);
        }
        outputBuffer.data = dataBuffer->data;
        outputBuffer.length = dataBuffer->length;
        outputBuffer.isDataSupportMemShare = false;
        outputBuffer.placement = ge::Placement::kPlacementDevice;
    }

    ge::GeExecutor executor;
    if ((!needMallocIndexes.empty()) && (!basync)) {
        std::vector<ge::TensorDesc> inputDesc;
        std::vector<ge::TensorDesc> outputDesc;
        (void)executor.GetModelDescInfo(modelId, inputDesc, outputDesc);
        if (outputDesc.size() < output->blobs.size()) {
            ACL_LOG_ERROR("[Check][OutputDesc] outputDesc size [%zu] mismatch with blobs size[%zu].",
                          outputDesc.size(), output->blobs.size());
            return ACL_ERROR_INVALID_PARAM;
        }

        for (auto &idx : needMallocIndexes) {
            auto &dataBuffer = output->blobs[idx].dataBuf;
            const size_t outputSize = static_cast<size_t>(outputDesc[idx].GetSize());
            if (outputSize > 0UL) {
                ACL_REQUIRES_CALL_RTS_OK(rtMalloc(reinterpret_cast<void **>(&dataBuffer->data), outputSize,
                    RT_MEMORY_HBM, acl::ACL_MODE_ID_U16), rtMalloc);
                dataBuffer->length = outputSize;
                outputData.blobs[idx].data = dataBuffer->data;
                outputData.blobs[idx].length = outputSize;
                ACL_LOG_DEBUG("ModelExecute, assign acl-malloced output addr to user-defined buffer, addr:[%p], "
                              "len:[%lu]", dataBuffer->data, dataBuffer->length);
            }
        }
    }

    ACL_LOG_INFO("call ge interface executor.ExecModel, modelId[%u], asyncMode[%d]",
        modelId, static_cast<int32_t>(basync));
    std::vector<ge::GeTensorDesc> outputGeDesc;
    const ge::Status ret = executor.ExecModel(modelId, stream, inputData, inputGeDesc,
        outputData, outputGeDesc, basync);
    if (ret != ge::SUCCESS) {
        ACL_LOG_CALL_ERROR("[Exec][Model]Execute model failed, ge result[%u], modelId[%u]", ret, modelId);
        return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
    }

    if (dynamicFlag) {
        for (size_t i = 0U; i < output->blobs.size(); ++i) {
            if (output->blobs[i].tensorDesc != nullptr) {
                aclDestroyTensorDesc(output->blobs[i].tensorDesc);
            }
            output->blobs[i].tensorDesc = aclCreateTensorDesc(ACL_DT_UNDEFINED, 0, nullptr, ACL_FORMAT_UNDEFINED);
        }
    }
    ACL_REQUIRES_LE(outputGeDesc.size(), output->blobs.size());
    for (size_t i = 0UL; i < outputGeDesc.size(); ++i) {
        if (output->blobs[i].tensorDesc != nullptr) {
            output->blobs[i].tensorDesc->dims.clear();
            const std::vector<int64_t> dims = outputGeDesc[i].GetShape().GetDims();
            const ge::Format format = outputGeDesc[i].GetFormat();
            const ge::DataType dataType = outputGeDesc[i].GetDataType();
            for (const auto &dim : dims) {
                output->blobs[i].tensorDesc->dims.push_back(dim);
            }
            if (format != ge::FORMAT_RESERVED) {
                output->blobs[i].tensorDesc->format = static_cast<aclFormat>(format);
            }
            if (dataType != ge::DT_UNDEFINED) {
                output->blobs[i].tensorDesc->dataType = static_cast<aclDataType>(dataType);
            }
        }

        auto &dataBuffer = output->blobs[i].dataBuf;
        if ((dataBuffer->data == nullptr) && (!basync)) {
            const auto outputSize = outputData.blobs[i].length;
            ACL_REQUIRES_CALL_RTS_OK(rtMalloc(reinterpret_cast<void **>(&dataBuffer->data), outputSize,
                RT_MEMORY_HBM, acl::ACL_MODE_ID_U16), rtMalloc);
            ACL_REQUIRES_CALL_RTS_OK(rtMemcpy(dataBuffer->data, outputSize, outputData.blobs[i].data,
                outputSize, RT_MEMCPY_DEVICE_TO_DEVICE), rtMemcpy);
            dataBuffer->length = outputSize;
            ACL_LOG_DEBUG("ModelExecute, assign acl-malloced output addr to user-defined buffer, addr:[%p], "
                          "len:[%lu]", dataBuffer->data, dataBuffer->length);
        }
    }

    ACL_LOG_INFO("successfully execute ModelExecute, modelId[%u]", modelId);
    return ACL_SUCCESS;
}

// get real tensor name from modelDesc, it will return nullptr if tensorName isn't in modelDesc
static const char_t *GetRealTensorName(const aclmdlDesc *const modelDesc, const std::string &tensorName)
{
    for (size_t idx = 0U; idx < modelDesc->inputDesc.size(); ++idx) {
        if (modelDesc->inputDesc[idx].name == tensorName) {
            return modelDesc->inputDesc[idx].name.c_str();
        }
    }

    for (size_t idx = 0U; idx < modelDesc->outputDesc.size(); ++idx) {
        if (modelDesc->outputDesc[idx].name == tensorName) {
            return modelDesc->outputDesc[idx].name.c_str();
        }
    }
    return nullptr;
}

static bool IsConvertTensorNameLegal(const aclmdlDesc *const modelDesc, const std::string &tensorName)
{
    return (GetRealTensorName(modelDesc, tensorName) == nullptr);
}

// current conversion tensor name illegal needs to be transformed
static bool TransConvertTensorNameToLegal(const aclmdlDesc *const modelDesc, std::string &tensorName)
{
    size_t depth = 0U;
    tensorName = tensorName + "_";
    std::queue<std::string> q;
    q.push(tensorName);
    constexpr size_t maxDepth = 3U;
    while (!q.empty()) {
        if (depth == maxDepth) {
            ACL_LOG_INFO("reach max depth[%zu], cannot generate legal convert tensor name", maxDepth);
            tensorName = tensorName.substr(0U, tensorName.size() - 1U);
            return false;
        }
        const size_t len = q.size();
        for (size_t idx = 0U; idx < len; ++idx) {
            std::string curTensorName = q.front();
            q.pop();
            for (char_t c = 'a'; c <= 'z'; ++c) {
                curTensorName += c;
                if (IsConvertTensorNameLegal(modelDesc, curTensorName)) {
                    tensorName = curTensorName;
                    return true;
                }
                q.push(curTensorName);
                curTensorName = curTensorName.substr(0U, curTensorName.size() - 1U);
            }
        }
        depth++;
    }
    return false;
}

// convert params to convertName
static void GetConvertTensorName(const aclmdlDesc *const modelDesc, const size_t idx,
    const TensorType tensorType, std::string &convertName)
{
    convertName = std::string(TENSOR_NAME_PREFIX) + "_" +
        std::string(MODEL_ID_STR) + "_" + std::to_string(modelDesc->modelId);
    if (tensorType == TensorType::INPUT_TENSOR_TYPE) {
        convertName += ("_" + std::string(TENSOR_INPUT_STR));
    } else {
        convertName += ("_" + std::string(TENSOR_OUTPUT_STR));
    }
    convertName += ("_" + std::to_string(idx));
    ACL_LOG_INFO("convert realname of tensor success, conversion name = %s", convertName.c_str());
}

// get tensor name to dims with or without realname
static aclError GetTensorDescNameToDims(const aclmdlDesc *const modelDesc, const std::string &realName,
    const TensorType tensorType, const size_t idx, aclmdlIODims *const dims)
{
    const size_t dimsNameLen = sizeof(dims->name);
    std::string tensorName;
    if ((realName.size() + 1U) > dimsNameLen) {
        // use conversion name because realname is too long
        ACL_LOG_INFO("use conversion name because real tensor name is over than %zu", dimsNameLen);
        GetConvertTensorName(modelDesc, idx, tensorType, tensorName);
        if (!IsConvertTensorNameLegal(modelDesc, tensorName)) {
            if (!TransConvertTensorNameToLegal(modelDesc, tensorName)) {
                ACL_LOG_WARN("cannot generate legal tensor name, use conversion name %s may has conflict risk",
                    tensorName.c_str());
            }
        }
    } else {
        tensorName = realName;
    }

    const auto ret = strncpy_s(dims->name, dimsNameLen, tensorName.c_str(), tensorName.size());
    if (ret != EOK) {
        ACL_LOG_INNER_ERROR("[Copy][Str]call strncpy_s failed, result = %d", ret);
        return ACL_ERROR_FAILURE;
    }
    return ACL_SUCCESS;
}

static aclError GetDims(const aclmdlDesc *const modelDesc, const TensorType tensorType, const DimsType dimsType,
    const size_t idx, aclmdlIODims *const dims)
{
    ACL_REQUIRES_NOT_NULL(dims);
    std::vector<aclmdlTensorDesc> desc;
    if (tensorType == TensorType::INPUT_TENSOR_TYPE) {
        desc = modelDesc->inputDesc;
    } else {
        desc = modelDesc->outputDesc;
    }

    const size_t descSize = desc.size();
    if (idx >= descSize) {
        ACL_LOG_INNER_ERROR("[Check][Params]GetDims failed, index[%zu] can not greater than or equal to tensor "
            "size[%zu]", idx, descSize);
        return ACL_ERROR_INVALID_PARAM;
    }

    const aclmdlTensorDesc &tensorDesc = desc[idx];
    const auto ret = GetTensorDescNameToDims(modelDesc, tensorDesc.name, tensorType, idx, dims);
    if (ret != ACL_SUCCESS) {
        ACL_LOG_INNER_ERROR("[Get][TensorDescName]get tensor desc name to dims failed, errorCode = %d", ret);
        return ret;
    }
    std::vector<int64_t> tensorDims;
    if (dimsType == DimsType::DIMS_TYPE_V1) {
        tensorDims = tensorDesc.dims;
    } else if (dimsType == DimsType::DIMS_TYPE_V2) {
        tensorDims = tensorDesc.dimsV2;
    } else {
        ACL_LOG_INNER_ERROR("[Check][dimsType]dims type[%d] is invalid", static_cast<int32_t>(dimsType));
        return ACL_ERROR_FAILURE;
    }

    const size_t dimSize = tensorDims.size();
    if (dimSize > static_cast<size_t>(ACL_MAX_DIM_CNT)) {
        ACL_LOG_INNER_ERROR("[Check][dimSize]get dims failed, dims count[%zu] can not larger than max[%d]",
            dims->dimCount, ACL_MAX_DIM_CNT);
        return ACL_ERROR_STORAGE_OVER_LIMIT;
    }
    dims->dimCount = dimSize;

    for (size_t i = 0U; i < dimSize; ++i) {
        dims->dims[i] = tensorDims[i];
    }

    return ACL_SUCCESS;
}

static aclError GetDimsRange(const aclmdlDesc *const modelDesc, const TensorType tensorType, const size_t idx,
                             aclmdlIODimsRange *const dimsRange)
{
    ACL_REQUIRES_NOT_NULL(dimsRange);
    const bool isDynamicGear = (!modelDesc->dynamicBatch.empty() || !modelDesc->dynamicDims.empty() ||
                          !modelDesc->dynamicHW.empty());
    if (isDynamicGear) {
        dimsRange->rangeCount = 0U;
        ACL_LOG_INFO("set rangeCount[%zu] in the dynamic gear model scenario success.", dimsRange->rangeCount);
        return ACL_SUCCESS;
    }

    std::vector<aclmdlTensorDesc> desc;
    if (tensorType == TensorType::INPUT_TENSOR_TYPE) {
        desc = modelDesc->inputDesc;
    } else {
        desc = modelDesc->outputDesc;
    }

    const size_t descSize = desc.size();
    if (idx >= descSize) {
        ACL_LOG_INNER_ERROR("[Check][Params]GetDimsRange failed, index[%zu] can not greater than or equal to tensor "
            "size[%zu]", idx, descSize);
        return ACL_ERROR_INVALID_PARAM;
    }

    const auto &tensorDesc = desc[idx];
    const auto &shapeRanges = tensorDesc.shapeRanges;
    const size_t dynamicDimSize = shapeRanges.size();
    constexpr size_t MIN = 0U;
    constexpr size_t MAX = 1U;
    if (dynamicDimSize > static_cast<size_t>(ACL_MAX_DIM_CNT)) {
        ACL_LOG_INNER_ERROR("[Check][dynamicDimSize]GetDimsRange failed, dim size[%zu] can not larger than max[%d]",
                            dynamicDimSize, ACL_MAX_DIM_CNT);
        return ACL_ERROR_INTERNAL_ERROR;
    }
    if (dynamicDimSize == 0U) {
        const auto &staticDims = tensorDesc.dims;
        const size_t staticDimSize = staticDims.size();
        if (staticDimSize > static_cast<size_t>(ACL_MAX_DIM_CNT)) {
            ACL_LOG_INNER_ERROR("[Check][staticDimSize]GetDimsRange failed, dim size[%zu] can not larger than max[%d]",
                                staticDimSize, ACL_MAX_DIM_CNT);
            return ACL_ERROR_INTERNAL_ERROR;
        }
        dimsRange->rangeCount = staticDimSize;
        ACL_LOG_INFO("set rangeCount[%zu] in the static model scenario success.", dimsRange->rangeCount);
        for (size_t i = 0U; i < staticDimSize; ++i) {
            dimsRange->range[i][MIN] = staticDims[i];
            dimsRange->range[i][MAX] = staticDims[i];
            ACL_LOG_INFO("set range[%zu][%zu] to [%ld] and range[%zu][%zu] to [%ld] success.", i, MIN,
                         dimsRange->range[i][MIN], i, MAX, dimsRange->range[i][MAX]);
        }
    } else {
        if (dynamicDimSize != tensorDesc.dims.size()) {
            ACL_LOG_INNER_ERROR("[Check][dynamicDimSize]GetDimsRange failed, size of shapeRanges[%zu] does not equal "
                                "to size of dims[%zu]", dynamicDimSize, tensorDesc.dims.size());
            return ACL_ERROR_INTERNAL_ERROR;
        }
        dimsRange->rangeCount = dynamicDimSize;
        ACL_LOG_INFO("set rangeCount[%zu] in the dynamic model scenario success.", dimsRange->rangeCount);
        for (size_t i = 0U; i < dynamicDimSize; ++i) {
            dimsRange->range[i][MIN] = shapeRanges[i].first;
            dimsRange->range[i][MAX] = shapeRanges[i].second;
            ACL_LOG_INFO("set range[%zu][%zu] to [%ld] and range[%zu][%zu] to [%ld] success.", i, MIN,
                         dimsRange->range[i][MIN], i, MAX, dimsRange->range[i][MAX]);
        }
    }

    return ACL_SUCCESS;
}

static aclError GetCurGearIndex(const aclmdlDesc *const modelDesc, const std::vector<uint64_t> &shapeInfo,
                                const int32_t dynamicType, size_t &curGearIndex)
{
    if (dynamicType == static_cast<int32_t>(ge::DYNAMIC_DIMS)) { // dynamic dims, type is 3
        ACL_LOG_DEBUG("Get dynamic dims gear index, dynamicType[%d], modelId[%u]",
                      dynamicType, modelDesc->modelId);
        for (size_t i = 0U; i < modelDesc->dynamicDims.size(); ++i) {
            // shapeInfo is current dims
            if (shapeInfo == modelDesc->dynamicDims[i]) {
                curGearIndex = i;
                return ACL_SUCCESS;
            }
        }
    } else {
        const size_t shapeSize = shapeInfo.size();
        if (shapeSize == DYNAMIC_BATCH_SIZE) { // dynamic batch, type is 1
            ACL_LOG_DEBUG("Get dynamic batch gear index, dynamicType[%d], modelId[%u]", dynamicType,
                          modelDesc->modelId);
            for (size_t i = 0U; i < modelDesc->dynamicBatch.size(); ++i) {
                // shapeInfo[0] is current batch size
                if (shapeInfo[0U] == modelDesc->dynamicBatch[i]) {
                    curGearIndex = i;
                    return ACL_SUCCESS;
                }
            }
        } else if (shapeSize == DYNAMIC_HW_SIZE) { // dynamic hw, type is 2
            ACL_LOG_DEBUG("Get dynamic hw gear index, dynamicType[%d], modelId[%u]", dynamicType, modelDesc->modelId);
            for (size_t i = 0U; i < modelDesc->dynamicHW.size(); ++i) {
                // shapeInfo is current hw
                if (shapeInfo == modelDesc->dynamicHW[i]) {
                    curGearIndex = i;
                    return ACL_SUCCESS;
                }
            }
        } else {
            ACL_LOG_INNER_ERROR("[Check][dynamicType]dynamicType[%d] is invalid", dynamicType);
        }
    }

    return ACL_ERROR_FAILURE;
}

static aclError GetCurOuputShapeInfo(const aclmdlDesc *const modelDesc, const size_t idex,
                                     const size_t curGearIndex, aclmdlIODims *const dims)
{
    ACL_LOG_DEBUG("curGearIndex is %zu, dynamicOutputShapeInfoSize is %zu , modelId is %u",
        curGearIndex, modelDesc->dynamicOutputShape.size(), modelDesc->modelId);
    for (auto &it : modelDesc->dynamicOutputShape) {
        if ((it.size() < MIN_OUTPUT_SHAPE_INFO_SIZE) || (it.size() > MAX_OUTPUT_SHAPE_INFO_SIZE)) {
            ACL_LOG_INNER_ERROR("[Check][dynamicOutputShape]output shape info size[%zu] is invalid, range is "
                "[%zu, %zu]", it.size(), MIN_OUTPUT_SHAPE_INFO_SIZE, MAX_OUTPUT_SHAPE_INFO_SIZE);
            return ACL_ERROR_FAILURE;
        }
        // -1 represents static output gear index value
        // it[0] is gear index and it[1] is output index
        if (((static_cast<int64_t>(curGearIndex) == it[0U]) || (it[0U] == -1)) &&
            (static_cast<int64_t>(idex) == it[1U])) {
            int32_t idx = 0;
            for (size_t i = 2U; i < it.size(); ++i) { // from the third element is shape info
                dims->dims[idx] = it[i];
                idx++;
            }
            dims->dimCount = it.size() - 2U;
            const aclmdlTensorDesc &tensorDesc = modelDesc->outputDesc[idex];
            const auto ret = GetTensorDescNameToDims(modelDesc, tensorDesc.name, TensorType::OUTPUT_TENSOR_TYPE, idex,
                                                     dims);
            if (ret != ACL_SUCCESS) {
                ACL_LOG_INNER_ERROR("[Get][TensorDescName]get tensor desc name to dims failed, errorCode = %d", ret);
                return ret;
            }
            return ACL_SUCCESS;
        }
    }

    return ACL_ERROR_FAILURE;
}

static void UpdateGraphOptions(const std::string &key, const std::string &value)
{
    auto options = ge::GetThreadLocalContext().GetAllGraphOptions();
    options[key] = value;
    ge::GetThreadLocalContext().SetGraphOption(options);
}

static const char *aclmdlGetNameByIndex(const std::vector<aclmdlTensorDesc> &desc, const size_t idx)
{
    if (idx >= desc.size()) {
        ACL_LOG_ERROR("[Check][index]get name by index failed, index[%zu] is larger than or equal to desc size[%zu]",
            idx, desc.size());
        const std::string errMsg = acl::AclErrorLogManager::FormatStr("cannot larger than or equal to desc size[%zu]",
            desc.size());
        acl::AclErrorLogManager::ReportInputError(acl::INVALID_PARAM_MSG,
            std::vector<std::string>({"param", "value", "reason"}),
            std::vector<std::string>({"index", std::to_string(idx), errMsg}));
        return "";
    }

    return desc[idx].name.c_str();
}

static aclFormat aclmdlGetFormat(const std::vector<aclmdlTensorDesc> &desc, const size_t idx)
{
    if (idx >= desc.size()) {
        ACL_LOG_INNER_ERROR("[Check][index]get data format by index failed, index[%zu] is larger "
            "than or equal to desc size[%zu]", idx, desc.size());
        return ACL_FORMAT_UNDEFINED;
    }

    return desc[idx].format;
}

static aclDataType aclmdlGetDataType(const std::vector<aclmdlTensorDesc> &desc, const size_t idx)
{
    if (idx >= desc.size()) {
        ACL_LOG_INNER_ERROR("[Check][Index]get data type by index failed, index[%zu] is larger than or "
            "equal to desc size[%zu]", idx, desc.size());
        return ACL_DT_UNDEFINED;
    }

    return desc[idx].dataType;
}

static aclError aclmdlGetIndexByName(const std::vector<aclmdlTensorDesc> &desc,
    const char_t *const name, size_t *const idx)
{
    ACL_REQUIRES_NOT_NULL(name);
    ACL_REQUIRES_NOT_NULL(idx);

    const std::string tensorName(name);
    for (size_t i = 0U; i < desc.size(); ++i) {
        if (desc[i].name == tensorName) {
            *idx = i;
            ACL_LOG_DEBUG("success to get tensor[%s] index[%zu]", name, *idx);
            return ACL_SUCCESS;
        }
    }

    ACL_LOG_INNER_ERROR("[Get][Index]get index by name failed, cannot find tensor name[%s]", name);
    return ACL_ERROR_INVALID_PARAM;
}

// try to transfer conversion name to real tensor name, it will return nullptr if conversion name isn't
// satisfy condition
static const char_t *TransTensorNameToReal(const aclmdlDesc *const modelDesc, const std::string &tensorName)
{
    std::vector<std::string> valArr;
    acl::StringUtils::Split(tensorName, '_', valArr);
    if ((valArr.size() != TENSOR_NAME_ATTR_NUM) && (valArr.size() != (TENSOR_NAME_ATTR_NUM + 1U))) {
        ACL_LOG_INNER_ERROR("[Check][Params]tensorName[%s] cannot be devided into %zu parts",
            tensorName.c_str(), TENSOR_NAME_ATTR_NUM);
        return nullptr;
    }
    if (valArr[0U] != TENSOR_NAME_PREFIX) {
        ACL_LOG_INNER_ERROR("[Check][Param]cannot find Attr[%s] in tensorName[%s]",
            TENSOR_NAME_PREFIX, tensorName.c_str());
        return nullptr;
    }
    const int32_t base = 10;
    if ((valArr[1U] == MODEL_ID_STR) && (acl::StringUtils::IsDigit(valArr[2U]))) {
        const auto modelId = strtoul(valArr[2U].c_str(), nullptr, base);
        if (modelId != modelDesc->modelId) {
            ACL_LOG_INNER_ERROR("[Check][modelId]modelId[%lu] is invalid, tensorName[%s]", modelId, tensorName.c_str());
            return nullptr;
        }
    } else {
        ACL_LOG_INNER_ERROR("[Check][modelId]cannot find attr[%s] or modelId in tensorName[%s]",
            MODEL_ID_STR, tensorName.c_str());
        return nullptr;
    }
    if (acl::StringUtils::IsDigit(valArr[4U])) {
        const auto idex = strtoul(valArr[4U].c_str(), nullptr, base);
        if (valArr[3U] == TENSOR_INPUT_STR) {
            if (idex >= modelDesc->inputDesc.size()) {
                ACL_LOG_INNER_ERROR("[Check][index]inputDesc index[%lu] should be in [0, %zu), tensorName[%s]",
                    idex, modelDesc->inputDesc.size(), tensorName.c_str());
                return nullptr;
            }
            return modelDesc->inputDesc[idex].name.c_str();
        }
        if (valArr[3U] == TENSOR_OUTPUT_STR) {
            if (idex >= modelDesc->outputDesc.size()) {
                ACL_LOG_INNER_ERROR("[Check][index]outputDesc index[%lu] should be in [0, %zu), tensorName[%s]", idex,
                    modelDesc->outputDesc.size(), tensorName.c_str());
                return nullptr;
            }
            return modelDesc->outputDesc[idex].name.c_str();
        }
    }

    ACL_LOG_INNER_ERROR("[Find][Attr]cannot find [input_%s] or [ouput_%s] in tensorName[%s]", valArr[4U].c_str(),
        valArr[4U].c_str(), tensorName.c_str());
    return nullptr;
}

static size_t aclmdlGetTensorSize(aclmdlTensorDesc &tensorDesc, size_t idx)
{
    std::vector<int64_t> &dims = tensorDesc.dims;
    bool needCalcByMaxShapeRange = false;
    for (size_t i = 0U; i < dims.size(); ++i) {
        if (dims[i] < 0) {
            needCalcByMaxShapeRange = true;
            break;
        }
    }

    if (tensorDesc.shapeRanges.empty()) {
        needCalcByMaxShapeRange = false;
    }

    if (needCalcByMaxShapeRange) {
        std::vector<std::pair<int64_t, int64_t>> &shapeRanges = tensorDesc.shapeRanges;
        const size_t elementTypeSize = aclDataTypeSize(tensorDesc.dataType);
        size_t outputSizeByMaxShapeRange = elementTypeSize;
        for (size_t i = 0U; i < shapeRanges.size(); ++i) {
            if (shapeRanges[i].second <= 0) {
                ACL_LOG_INFO("max shape of shapeRanges[%zu] is [%ld], index[%zu]",
                             i, shapeRanges[i].second, idx);
                return 0U;
            }
            if (acl::CheckSizeTMultiOverflow(outputSizeByMaxShapeRange, static_cast<size_t>(shapeRanges[i].second),
                                             outputSizeByMaxShapeRange) == ACL_ERROR_FAILURE) {
                return 0U;
            }
        }
        return outputSizeByMaxShapeRange;
    }

    return tensorDesc.size;
}

static void GetTensorInfo(std::vector<aclmdlTensorDesc> &inputDesc, const gert::ModelIoDesc *const inputs,
                          size_t &inputNum)
{
    for (size_t i = 0U; i < inputNum; ++i) {
        aclmdlTensorDesc tensorDesc;
        const auto tempPtr = inputs + i;
        tensorDesc.size = static_cast<size_t>(tempPtr->GetSize());
        std::string inputStr;
        const char_t *const inputName = tempPtr->GetName();
        if (inputName != nullptr) {
            inputStr = std::string(inputName);
        }
        tensorDesc.name = inputStr;
        tensorDesc.format = static_cast<aclFormat>(tempPtr->GetOriginFormat());
        tensorDesc.dataType = static_cast<aclDataType>(tempPtr->GetDataType());
        const gert::Shape &shape = tempPtr->GetOriginShape();
        for (size_t j = 0U; j < shape.GetDimNum(); ++j) {
            tensorDesc.dims.emplace_back(shape.GetDim(j));
        }
        const auto &shapeRangeVector = tempPtr->GetOriginShapeRangeVector();
        (void)tensorDesc.shapeRanges.insert(tensorDesc.shapeRanges.cend(),
                                            shapeRangeVector.cbegin(), shapeRangeVector.cend());
        const gert::Shape &aippShapeV2 = tempPtr->GetAippShape();
        for (size_t j = 0U; j < aippShapeV2.GetDimNum(); ++j) {
            tensorDesc.dimsV2.emplace_back(aippShapeV2.GetDim(j));
        }
        inputDesc.push_back(tensorDesc);
    }
}

static aclError RuntimeV2GetDesc(aclmdlDesc * const modelDesc, const uint32_t modelId)
{
    const auto executor = acl::AclResourceManager::GetInstance().GetExecutor(modelId);
    if (executor == nullptr) {
        ACL_LOG_ERROR("input modelId[%u] is invalid while get executor", modelId);
        return static_cast<aclError>(ACL_ERROR_GE_EXEC_MODEL_ID_INVALID);
    }
    const auto &geModelDesc = executor->GetModelDesc();
    size_t inputNum = 0U;
    size_t outputNum = 0U;
    const gert::ModelIoDesc *const inputs = geModelDesc.GetAllInputsDesc(inputNum);
    GetTensorInfo(modelDesc->inputDesc, inputs, inputNum);
    const gert::ModelIoDesc *const outputs = geModelDesc.GetAllOutputsDesc(outputNum);
    GetTensorInfo(modelDesc->outputDesc, outputs, outputNum);

    modelDesc->modelId = modelId;
    aclError retVal = acl::RuntimeV2GetDynamicTensorInfo(modelDesc, geModelDesc);
    if (retVal != ACL_SUCCESS) {
        ACL_LOG_INNER_ERROR("[Get][DynamicTensorInfo]get model dynamic info failed, result[%d], model id[%u]",
            retVal, modelId);
        return retVal;
    }

    retVal = acl::RuntimeV2GetModelOutputShapeInfo(modelDesc, geModelDesc);
    if (retVal != ACL_SUCCESS) {
        ACL_LOG_INNER_ERROR("[Get][ModelOutputShapeInfo]get model output shape info failed, result[%d], model id[%u]",
            retVal, modelId);
        return retVal;
    }

    ACL_LOG_INFO("successfully execute aclmdlGetDesc, model id[%u]", modelId);
    return ACL_SUCCESS;
}
}

aclError aclmdlGetDesc(aclmdlDesc *modelDesc, uint32_t modelId)
{
    ACL_PROFILING_REG(acl::AclProfType::AclmdlGetDesc);
    ACL_STAGES_REG(acl::ACL_STAGE_GET, acl::ACL_STAGE_DEFAULT);
    ACL_LOG_INFO("start to execute aclmdlGetDesc, model id[%u]", modelId);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelDesc);
    modelDesc->Clear();
    if ((acl::AclResourceManager::GetInstance().IsRuntimeV2Enable(true)) &&
        (acl::AclResourceManager::GetInstance().GetExecutor(modelId) != nullptr)) {
        return acl::RuntimeV2GetDesc(modelDesc, modelId);
    }

    std::vector<ge::TensorDesc> inputDesc;
    std::vector<ge::TensorDesc> outputDesc;
    ge::GeExecutor executor;
    ge::Status ret = executor.GetModelDescInfo(modelId, inputDesc, outputDesc);
    if (ret != ge::SUCCESS) {
        ACL_LOG_CALL_ERROR("[Get][ModelDescInfo]get model description failed, ge result[%u], model id[%u]",
            ret, modelId);
        return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
    }

    std::vector<ge::TensorDesc> inputDescV2;
    std::vector<ge::TensorDesc> outputDescV2;
    ret = executor.GetModelDescInfo(modelId, inputDescV2, outputDescV2, true);
    if (ret != ge::SUCCESS) {
        ACL_LOG_CALL_ERROR("[Get][ModelDescInfo]get model description v2 failed, ge result[%u], model id[%u]",
            ret, modelId);
        return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
    }

    if ((inputDescV2.size() < inputDesc.size()) || (outputDescV2.size() < outputDesc.size())) {
        ACL_LOG_CALL_ERROR("[Get][ModelDescInfo]description v2 size less than description v1 size, model id[%u]",
            modelId);
        return ACL_ERROR_FAILURE;
    }

    for (size_t i = 0U; i < inputDesc.size(); ++i) {
        ge::AscendString inputName;
        aclmdlTensorDesc tensorDesc;
        tensorDesc.size = static_cast<size_t>(inputDesc[i].GetSize());
        const ge::graphStatus retStatus = inputDesc[i].GetName(inputName);
        if (retStatus != ge::GRAPH_SUCCESS) {
            ACL_LOG_CALL_ERROR("[Get][TensorName]the %zu input tensor GetName failed.", i);
            return ACL_GET_ERRCODE_GE(static_cast<int32_t>(retStatus));
        }
        std::string inputStr;
        if (inputName.GetString() != nullptr) {
            inputStr = std::string(inputName.GetString());
        }
        tensorDesc.name = inputStr;
        tensorDesc.format = static_cast<aclFormat>(inputDesc[i].GetFormat());
        tensorDesc.dataType = static_cast<aclDataType>(inputDesc[i].GetDataType());
        const ge::Shape shape = inputDesc[i].GetShape();
        tensorDesc.dims = shape.GetDims();
        const ge::Shape shapeV2 = inputDescV2[i].GetShape();
        tensorDesc.dimsV2 = shapeV2.GetDims();
        (void)inputDesc[i].GetShapeRange(tensorDesc.shapeRanges);
        modelDesc->inputDesc.push_back(tensorDesc);
    }

    for (size_t i = 0U; i < outputDesc.size(); ++i) {
        ge::AscendString outputName;
        aclmdlTensorDesc tensorDesc;
        tensorDesc.size = static_cast<size_t>(outputDesc[i].GetSize());
        const ge::graphStatus retStatus = outputDesc[i].GetName(outputName);
        if (retStatus != ge::GRAPH_SUCCESS) {
            ACL_LOG_CALL_ERROR("[Get][TensorName]the %zu output tensor GetName failed.", i);
            return ACL_GET_ERRCODE_GE(static_cast<int32_t>(retStatus));
        }
        std::string outputStr;
        if (outputName.GetString() != nullptr) {
            outputStr = std::string(outputName.GetString());
        }
        tensorDesc.name = outputStr;
        tensorDesc.format = static_cast<aclFormat>(outputDesc[i].GetFormat());
        tensorDesc.dataType = static_cast<aclDataType>(outputDesc[i].GetDataType());
        const ge::Shape shape = outputDesc[i].GetShape();
        tensorDesc.dims = shape.GetDims();
        const ge::Shape shapeV2 = outputDescV2[i].GetShape();
        tensorDesc.dimsV2 = shapeV2.GetDims();
        (void)outputDesc[i].GetShapeRange(tensorDesc.shapeRanges);
        modelDesc->outputDesc.push_back(tensorDesc);
    }

    modelDesc->modelId = modelId;
    aclError retVal = acl::GetDynamicTensorInfo(modelDesc);
    if (retVal != ACL_SUCCESS) {
        ACL_LOG_INNER_ERROR("[Get][DynamicTensorInfo]get model dynamic info failed, result[%d], model id[%u]",
            retVal, modelId);
        return retVal;
    }

    retVal = acl::GetModelOutputShapeInfo(modelDesc);
    if (retVal != ACL_SUCCESS) {
        ACL_LOG_INNER_ERROR("[Get][ModelOutputShapeInfo]get model output shape info failed, result[%d], model id[%u]",
            retVal, modelId);
        return retVal;
    }

    ACL_LOG_INFO("successfully execute aclmdlGetDesc, model id[%u]", modelId);
    return ACL_SUCCESS;
}

static void GetModelTensorDesc(const ge::ModelInOutInfo &info, aclmdlDesc *modelDesc, bool isInput)
{
    const auto &descs = isInput ? info.input_desc : info.output_desc;
    for (const auto &desc : descs) {
        aclmdlTensorDesc tmpDesc;
        tmpDesc.name = desc.name;
        tmpDesc.size = desc.size;
        tmpDesc.format = (desc.format != ge::FORMAT_RESERVED) ?
                static_cast<aclFormat>(desc.format) : ACL_FORMAT_UNDEFINED;
        tmpDesc.dataType = (desc.dataType != ge::DT_UNDEFINED) ?
                static_cast<aclDataType>(desc.dataType) : ACL_DT_UNDEFINED;
        tmpDesc.dims = desc.dims;
        tmpDesc.dimsV2 = desc.dimsV2;
        tmpDesc.shapeRanges = desc.shape_ranges;
        if (isInput) {
            modelDesc->inputDesc.emplace_back(tmpDesc);
        } else {
            modelDesc->outputDesc.emplace_back(tmpDesc);
        }
    }
}

static aclError GetDescFromMem(const ge::ModelData &modelData, const ge::GeExecutor &executor, aclmdlDesc *modelDesc)
{
    ACL_LOG_INFO("call ge interface GetModelDescInfoFromMem");
    ge::ModelInOutInfo info;
    const auto ret = executor.GetModelDescInfoFromMem(modelData, info);
    if (ret != ge::SUCCESS) {
        ACL_LOG_CALL_ERROR("GetModelDescInfoFromMem failed");
        return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
    }
    GetModelTensorDesc(info, modelDesc, true);
    GetModelTensorDesc(info, modelDesc, false);
    modelDesc->dynamicBatch = info.dynamic_batch;
    modelDesc->dynamicHW = info.dynamic_hw;
    modelDesc->dynamicDims = info.dynamic_dims;
    ACL_REQUIRES_OK(acl::GetModelOutputShapeInfoHelp(modelDesc, info.dynamic_output_shape));
    modelDesc->dataNameOrder = info.data_name_order;
    return ACL_SUCCESS;
}

aclError aclmdlGetDescFromFile(aclmdlDesc *modelDesc, const char *modelPath)
{
    ACL_PROFILING_REG(acl::AclProfType::AclmdlGetDesc);
    ACL_STAGES_REG(acl::ACL_STAGE_GET, acl::ACL_STAGE_DEFAULT);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelDesc);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelPath);
    ACL_LOG_INFO("start to execute aclmdlGetDescFromFile, path is %s", modelPath);
    modelDesc->Clear();
    ge::GeExecutor executor;
    ge::ModelData data;
    ACL_LOG_INFO("call ge interface executor.LoadDataFromFile, path is %s", modelPath);
    const ge::Status ret = executor.LoadDataFromFile(modelPath, data);
    std::shared_ptr<void> dataAuto;
    dataAuto.reset(data.model_data, [](const void * const p) { delete[] static_cast<const uint8_t *>(p); });
    if (ret != ge::SUCCESS) {
        ACL_LOG_CALL_ERROR("[Model][FromFile]load model from file[%s] failed, ge result[%u]", modelPath, ret);
        return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
    }
    ACL_REQUIRES_OK(GetDescFromMem(data, executor, modelDesc));
    ACL_LOG_INFO("end to execute aclmdlGetDescFromFile, path is %s", modelPath);
    return ACL_SUCCESS;
}

aclError aclmdlGetDescFromMem(aclmdlDesc *modelDesc, const void *model, size_t modelSize)
{
    ACL_PROFILING_REG(acl::AclProfType::AclmdlGetDesc);
    ACL_STAGES_REG(acl::ACL_STAGE_GET, acl::ACL_STAGE_DEFAULT);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelDesc);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(model);
    ACL_REQUIRES_POSITIVE_WITH_INPUT_REPORT(modelSize);
    ACL_LOG_INFO("start to execute aclmdlGetDescFromMem, modelSize is %zu", modelSize);
    modelDesc->Clear();
    ge::GeExecutor executor;
    ge::ModelData modelData;
    modelData.model_data = const_cast<void *>(model);
    modelData.model_len = static_cast<uint64_t>(modelSize);
    ACL_REQUIRES_OK(GetDescFromMem(modelData, executor, modelDesc));
    ACL_LOG_INFO("end to execute aclmdlGetDescFromMem, modelSize is %zu", modelSize);
    return ACL_SUCCESS;
}

size_t aclmdlGetNumInputs(aclmdlDesc *modelDesc)
{
    if (modelDesc == nullptr) {
        return 0U;
    }

    return modelDesc->inputDesc.size();
}

size_t aclmdlGetNumOutputs(aclmdlDesc *modelDesc)
{
    if (modelDesc == nullptr) {
        return 0U;
    }

    return modelDesc->outputDesc.size();
}

size_t aclmdlGetInputSizeByIndex(aclmdlDesc *modelDesc, size_t index)
{
    if ((modelDesc == nullptr) || (index >= modelDesc->inputDesc.size())) {
        ACL_LOG_INNER_ERROR("input param is invalid, modelDesc[%p], index[%zu]", modelDesc, index);
        return 0U;
    }

    aclmdlTensorDesc &tensorDesc = modelDesc->inputDesc[index];
    return acl::aclmdlGetTensorSize(tensorDesc, index);
}

size_t aclmdlGetOutputSizeByIndex(aclmdlDesc *modelDesc, size_t index)
{
    if ((modelDesc == nullptr) || (index >= modelDesc->outputDesc.size())) {
        ACL_LOG_INNER_ERROR("input param is invalid, index[%zu]", index);
        return 0U;
    }
    aclmdlTensorDesc &tensorDesc = modelDesc->outputDesc[index];
    return acl::aclmdlGetTensorSize(tensorDesc, index);
}

aclmdlExecConfigHandle *aclmdlCreateExecConfigHandle()
{
    return new(std::nothrow) aclmdlExecConfigHandle();
}

aclError aclmdlDestroyExecConfigHandle(const aclmdlExecConfigHandle *handle)
{
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(handle);
    ACL_DELETE_AND_SET_NULL(handle);
    return ACL_SUCCESS;
}

aclmdlDataset *aclmdlCreateDataset()
{
    ACL_ADD_APPLY_TOTAL_COUNT(acl::ACL_STATISTICS_CREATE_DESTROY_DATASET);
    ACL_ADD_APPLY_SUCCESS_COUNT(acl::ACL_STATISTICS_CREATE_DESTROY_DATASET);
    return new(std::nothrow) aclmdlDataset();
}

aclError aclmdlDestroyDataset(const aclmdlDataset *dataset)
{
    ACL_ADD_RELEASE_TOTAL_COUNT(acl::ACL_STATISTICS_CREATE_DESTROY_DATASET);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dataset);
    for (size_t i = 0U; i < dataset->blobs.size(); ++i) {
        ACL_DELETE_ARRAY_AND_SET_NULL((const_cast<aclmdlDataset *>(dataset))->blobs[i].tensorDesc);
    }
    ACL_DELETE_AND_SET_NULL(dataset);
    ACL_ADD_RELEASE_SUCCESS_COUNT(acl::ACL_STATISTICS_CREATE_DESTROY_DATASET);
    return ACL_SUCCESS;
}

aclError aclmdlAddDatasetBuffer(aclmdlDataset *dataset, aclDataBuffer *dataBuffer)
{
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dataset);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dataBuffer);
    const acl::AclModelTensor tensor = acl::AclModelTensor(dataBuffer, nullptr);
    dataset->blobs.push_back(tensor);
    return ACL_SUCCESS;
}

size_t aclmdlGetDatasetNumBuffers(const aclmdlDataset *dataset)
{
    if (dataset == nullptr) {
        ACL_LOG_ERROR("[Check][Dataset]input param[dataset] is null");
        acl::AclErrorLogManager::ReportInputError(acl::INVALID_NULL_POINTER_MSG,
            std::vector<std::string>({"param"}),
            std::vector<std::string>({"dataset"}));
        return 0U;
    }

    return dataset->blobs.size();
}

aclDataBuffer *aclmdlGetDatasetBuffer(const aclmdlDataset *dataset, size_t index)
{
    if ((dataset == nullptr) || (index >= dataset->blobs.size())) {
        ACL_LOG_ERROR("[Check][Params]input param is invalid, dataset[%p], index[%zu]", dataset, index);
        const std::string errMsg = acl::AclErrorLogManager::FormatStr("dataset[%p], index[%zu]", dataset, index);
        acl::AclErrorLogManager::ReportInputError(acl::INVALID_PARAM_MSG,
            std::vector<std::string>({"param", "value", "reason"}),
            std::vector<std::string>({"input param", errMsg, "check failed"}));
        return nullptr;
    }

    return dataset->blobs[index].dataBuf;
}

aclTensorDesc *aclmdlGetDatasetTensorDesc(const aclmdlDataset *dataset, size_t index)
{
    ACL_REQUIRES_NOT_NULL_RET_NULL_INPUT_REPORT(dataset);
    if (index >= dataset->blobs.size()) {
        ACL_LOG_ERROR("[Check][Index]input param index[%zu] must be smaller than output databuf size[%zu]",
                      index, dataset->blobs.size());
        acl::AclErrorLogManager::ReportInputError(acl::INVALID_PARAM_MSG,
            std::vector<std::string>({"param", "value", "reason"}),
            std::vector<std::string>({"index", std::to_string(index), "must be smaller than output databuf size"}));
        return nullptr;
    }
    return dataset->blobs[index].tensorDesc;
}

aclError aclmdlSetDatasetTensorDesc(aclmdlDataset *dataset, aclTensorDesc *tensorDesc, size_t index)
{
    ACL_REQUIRES_NOT_NULL(dataset);
    if (index >= dataset->blobs.size()) {
        ACL_LOG_ERROR("[Check][Index]input param index[%zu] must be smaller than input databuf size[%zu]",
                      index, dataset->blobs.size());
        acl::AclErrorLogManager::ReportInputError(acl::INVALID_PARAM_MSG,
            std::vector<std::string>({"param", "value", "reason"}),
            std::vector<std::string>({"index", std::to_string(index), "must be smaller than input databuf size"}));
        return ACL_ERROR_INVALID_PARAM;
    }

    if (tensorDesc == nullptr) {
        ACL_DELETE_AND_SET_NULL(dataset->blobs[index].tensorDesc);
        ACL_LOG_INFO("Set tensorDesc for tensor[%zu] successfully, tensorDesc is nullptr", index);
        return ACL_SUCCESS;
    }

    if (dataset->blobs[index].tensorDesc == nullptr) {
        dataset->blobs[index].tensorDesc = new(std::nothrow) aclTensorDesc[1]{*tensorDesc};
        ACL_CHECK_MALLOC_RESULT(dataset->blobs[index].tensorDesc);
    } else {
        *(dataset->blobs[index].tensorDesc) = *tensorDesc;
    }
    ACL_LOG_INFO("Set tensorDesc %s for tensor[%zu] successfully", tensorDesc->DebugString().c_str(), index);
    return ACL_SUCCESS;
}

static aclError UnloadRt2Model(const uint32_t modelId)
{
    const auto executor = acl::AclResourceManager::GetInstance().GetExecutor(modelId);
    ge::graphStatus ret = ge::GRAPH_SUCCESS;
    if (executor != nullptr) {
        ret  = executor->UnLoad();
    } else {
        ACL_LOG_ERROR("modelId[%u] is invalid", modelId);
        return static_cast<aclError>(ACL_ERROR_GE_EXEC_MODEL_ID_INVALID);
    }
    if (ret != ge::GRAPH_SUCCESS) {
        ACL_LOG_CALL_ERROR("[Unload][Model]failed to unload model, modelId is %u, errorCode is %u", modelId, ret);
        return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
    }
    return acl::AclResourceManager::GetInstance().DeleteExecutor(modelId);
}

static aclError UnloadModelInner(const uint32_t modelId)
{
    if ((acl::AclResourceManager::GetInstance().IsRuntimeV2Enable(true)) &&
        (acl::AclResourceManager::GetInstance().GetExecutor(modelId) != nullptr)) {
        const auto ret = UnloadRt2Model(modelId);
        if (ret != ACL_SUCCESS) {
            ACL_LOG_ERROR("failed to unload model, modelId is %u, errorCode is %u", modelId, ret);
            return ret;
        }
    } else {
        ge::GeExecutor executor;
        ACL_LOG_INFO("call ge interface executor.UnloadModel, modelId[%u]", modelId);
        const ge::Status ret = executor.UnloadModel(modelId);
        if (ret != ge::SUCCESS) {
            ACL_LOG_CALL_ERROR("[Unload][Model]model unload failed, ge result[%u], modelId[%u]", ret, modelId);
            return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
        }
    }
    return ACL_SUCCESS;
}

static aclError BundleLoadFromMem(const void *model, size_t modelSize,
                                  const std::string &modelPath, uint32_t *bundleId)
{
    // get bundle num from file header
    bool isBundleOm = false;
    std::vector<std::pair<size_t, size_t>> offsetAndSize;
    ACL_REQUIRES_OK(acl::GetBundleNumAndOffset(model, modelSize, isBundleOm, offsetAndSize));
    if (!isBundleOm) {
        ACL_LOG_ERROR("this is not bundle om, please check");
        return ACL_ERROR_INVALID_PARAM;
    }
    std::vector<acl::BundleInfo> bundleInfos;
    auto rtSession = acl::AclResourceManager::GetInstance().CreateRtSession();
    ACL_REQUIRES_NOT_NULL(rtSession);
    for (const auto &offsetSize : offsetAndSize) {
        acl::BundleInfo bundleInfo{};
        uint32_t currentModelId = 0U;
        bool isSupportRT2 = false;
        void *currentModePtr = ge::ValueToPtr(ge::PtrToValue(model) + offsetSize.first);
        ACL_REQUIRES_OK(acl::IsSupportRuntimeV2WithModelData(currentModePtr, offsetSize.second, isSupportRT2));
        aclError ret = ACL_SUCCESS;
        if (isSupportRT2) {
            ret = acl::RuntimeV2ModelLoadFromMemWithMem(currentModePtr, offsetSize.second, modelPath,
                                                        &currentModelId, nullptr, 0U, nullptr, 0, rtSession);
        } else {
            ret = acl::ModelLoadFromMemWithMem(currentModePtr, offsetSize.second, modelPath,
                                               &currentModelId, nullptr, 0U, nullptr, 0U, nullptr, 0, rtSession);
        }
        if (ret != ACL_SUCCESS) {
            for (const auto &ele : bundleInfos) {
                (void)UnloadModelInner(ele.modelId);
            }
            return ret;
        }
        bundleInfo.modelId = currentModelId;
        bundleInfos.emplace_back(bundleInfo);
    }
    acl::AclResourceManager::GetInstance().AddExecutor(*bundleId, nullptr, rtSession);
    acl::AclResourceManager::GetInstance().AddBundleInfo(*bundleId, bundleInfos);
    return ACL_SUCCESS;
}

aclError aclmdlBundleLoadFromFile(const char *modelPath, uint32_t *bundleId)
{
    ACL_STAGES_REG(acl::ACL_STAGE_LOAD, acl::ACL_STAGE_DEFAULT);
    ACL_PROFILING_REG(acl::AclProfType::AclmdlBundleLoadFromFile);
    ACL_ADD_APPLY_TOTAL_COUNT(acl::ACL_STATISTICS_CREATE_LOAD_UNLOAD_MODEL);
    ACL_LOG_INFO("start to execute aclmdlBundleLoadFromFile");
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelPath);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(bundleId);

    // 1. load model data from file
    ge::ModelData modelData;
    modelData.om_path = modelPath;
    ge::graphStatus ret = ge::GRAPH_SUCCESS;
    ACL_LOG_INFO("call ge interface gert::LoadDataFromFile");
    ret = gert::LoadDataFromFile(modelPath, modelData);
    std::shared_ptr<void> data;
    data.reset(modelData.model_data, [](const void * const p) { delete[] static_cast<const uint8_t *>(p); });
    if (ret != ge::GRAPH_SUCCESS) {
        ACL_LOG_CALL_ERROR("[Load][Model]failed to load model from file by runtime2.0, ge errorCode is %u", ret);
        return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
    }

    ACL_REQUIRES_OK(BundleLoadFromMem(modelData.model_data, modelData.model_len, modelPath, bundleId));
    ACL_ADD_APPLY_SUCCESS_COUNT(acl::ACL_STATISTICS_CREATE_LOAD_UNLOAD_MODEL);
    ACL_LOG_INFO("successfully execute aclmdlBundleLoadFromFile, bundle id is %u", *bundleId);
    return ACL_SUCCESS;
}

aclError aclmdlBundleLoadFromMem(const void *model,  size_t modelSize, uint32_t *bundleId)
{
    ACL_PROFILING_REG(acl::AclProfType::AclmdlBundleLoadFromMem);
    ACL_STAGES_REG(acl::ACL_STAGE_LOAD, acl::ACL_STAGE_DEFAULT);
    ACL_ADD_APPLY_TOTAL_COUNT(acl::ACL_STATISTICS_CREATE_LOAD_UNLOAD_MODEL);
    ACL_LOG_INFO("start to execute aclmdlBundleLoadFromMem, modelSize[%zu]", modelSize);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(model);
    ACL_REQUIRES_POSITIVE_WITH_INPUT_REPORT(modelSize);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(bundleId);

    ACL_REQUIRES_OK(BundleLoadFromMem(model, modelSize, "", bundleId));

    ACL_LOG_INFO("execute aclmdlBundleLoadFromMem success, bundleId[%u]", *bundleId);
    ACL_ADD_APPLY_SUCCESS_COUNT(acl::ACL_STATISTICS_CREATE_LOAD_UNLOAD_MODEL);
    return ACL_SUCCESS;
}

aclError aclmdlLoadFromFile(const char *modelPath, uint32_t *modelId)
{
    ACL_STAGES_REG(acl::ACL_STAGE_LOAD, acl::ACL_STAGE_DEFAULT);
    ACL_PROFILING_REG(acl::AclProfType::AclmdlLoadFromFile);
    ACL_ADD_APPLY_TOTAL_COUNT(acl::ACL_STATISTICS_CREATE_LOAD_UNLOAD_MODEL);
    ACL_LOG_INFO("start to execute aclmdlLoadFromFile");
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelPath);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelId);
    aclError ret = ACL_SUCCESS;
    bool isSupportRT2 = false;
    ACL_REQUIRES_OK(acl::IsSupportRuntimeV2WithModelPath(modelPath, isSupportRT2));
    if (isSupportRT2) {
        ret = acl::RuntimeV2ModelLoadFromFileWithMem(modelPath, modelId, nullptr, 0U, 0);
    } else {
        ret = acl::ModelLoadFromFileWithMem(modelPath, modelId, nullptr, 0U, nullptr, 0U, 0);
    }
    if (ret != ACL_SUCCESS) {
        ACL_LOG_ERROR("Load model from file failed!");
        return ret;
    }
    ACL_ADD_APPLY_SUCCESS_COUNT(acl::ACL_STATISTICS_CREATE_LOAD_UNLOAD_MODEL);
    ACL_LOG_INFO("successfully execute aclmdlLoadFromFile");
    return ACL_SUCCESS;
}

aclError aclmdlLoadFromFileWithMem(const char *modelPath, uint32_t *modelId,
                                   void *workPtr, size_t workSize,
                                   void *weightPtr, size_t weightSize)
{
    ACL_STAGES_REG(acl::ACL_STAGE_LOAD, acl::ACL_STAGE_DEFAULT);
    ACL_PROFILING_REG(acl::AclProfType::AclmdlLoadFromFileWithMem);
    ACL_ADD_APPLY_TOTAL_COUNT(acl::ACL_STATISTICS_CREATE_LOAD_UNLOAD_MODEL);
    ACL_LOG_INFO("start to execute aclmdlLoadFromFileWithMem, workSize[%zu], weightSize[%zu]", workSize, weightSize);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelPath);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelId);
    aclError ret = ACL_SUCCESS;
    bool isSupportRT2 = false;
    ACL_REQUIRES_OK(acl::IsSupportRuntimeV2WithModelPath(modelPath, isSupportRT2));
    if (isSupportRT2) {
        ret = acl::RuntimeV2ModelLoadFromFileWithMem(modelPath, modelId, weightPtr, weightSize, 0);
    } else {
        ret = acl::ModelLoadFromFileWithMem(modelPath, modelId, workPtr, workSize, weightPtr, weightSize, 0);
    }
    if (ret != ACL_SUCCESS) {
        return ret;
    }
    ACL_LOG_INFO("Load model from file[%s] with memory success, modelId[%u]", modelPath, *modelId);
    ACL_ADD_APPLY_SUCCESS_COUNT(acl::ACL_STATISTICS_CREATE_LOAD_UNLOAD_MODEL);
    return ACL_SUCCESS;
}

aclError aclmdlLoadFromMem(const void *model, size_t modelSize, uint32_t *modelId)
{
    ACL_PROFILING_REG(acl::AclProfType::AclmdlLoadFromMem);
    ACL_STAGES_REG(acl::ACL_STAGE_LOAD, acl::ACL_STAGE_DEFAULT);
    ACL_ADD_APPLY_TOTAL_COUNT(acl::ACL_STATISTICS_CREATE_LOAD_UNLOAD_MODEL);
    ACL_LOG_INFO("start to execute aclmdlLoadFromMem, modelSize[%zu]", modelSize);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(model);
    ACL_REQUIRES_POSITIVE_WITH_INPUT_REPORT(modelSize);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelId);
    bool isSupportRT2 = false;
    ACL_REQUIRES_OK(acl::IsSupportRuntimeV2WithModelData(model, modelSize, isSupportRT2));
    aclError ret = ACL_SUCCESS;
    if (isSupportRT2) {
        ret = acl::RuntimeV2ModelLoadFromMemWithMem(model, modelSize, "", modelId, nullptr, 0U, nullptr, 0);
    } else {
        ret = acl::ModelLoadFromMemWithMem(model, modelSize, "", modelId, nullptr, 0U, nullptr, 0U, nullptr, 0);
    }
    if (ret != ACL_SUCCESS) {
        return ret;
    }

    ACL_LOG_INFO("Load model from data success, modelId[%u]", *modelId);
    ACL_ADD_APPLY_SUCCESS_COUNT(acl::ACL_STATISTICS_CREATE_LOAD_UNLOAD_MODEL);
    return ACL_SUCCESS;
}

// get some info from bundleId
aclError aclmdlBundleGetModelNum(uint32_t bundleId, size_t *modelNum)
{
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelNum);
    std::vector<acl::BundleInfo> bundleInfos;
    ACL_REQUIRES_OK(acl::AclResourceManager::GetInstance().GetBundleInfo(bundleId, bundleInfos));
    *modelNum = bundleInfos.size();
    ACL_LOG_INFO("get bundleId %u model num %zu", bundleId, *modelNum);
    return ACL_SUCCESS;
}

aclError aclmdlBundleGetModelId(uint32_t bundleId, size_t index, uint32_t *modelId)
{
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelId);
    std::vector<acl::BundleInfo> bundleInfos;
    ACL_REQUIRES_OK(acl::AclResourceManager::GetInstance().GetBundleInfo(bundleId, bundleInfos));
    if (index >= bundleInfos.size()) {
      ACL_LOG_ERROR("bundleId %u input index %zu should be smaller than bundle size %zu",
                    bundleId, index, bundleInfos.size());
      return ACL_ERROR_INVALID_PARAM;
    }
    *modelId = bundleInfos[index].modelId;
    ACL_LOG_INFO("get bundleId %u index %zu model id %u", bundleId, index, *modelId);
    return ACL_SUCCESS;
}

aclError aclmdlLoadFromMemWithMem(const void *model, size_t modelSize,
                                  uint32_t *modelId, void *workPtr, size_t workSize,
                                  void *weightPtr, size_t weightSize)
{
    ACL_PROFILING_REG(acl::AclProfType::AclmdlLoadFromMemWithMem);
    ACL_STAGES_REG(acl::ACL_STAGE_LOAD, acl::ACL_STAGE_DEFAULT);
    ACL_ADD_APPLY_TOTAL_COUNT(acl::ACL_STATISTICS_CREATE_LOAD_UNLOAD_MODEL);
    ACL_LOG_INFO("start to execute aclmdlLoadFromMemWithMem, modelSize[%zu], workSize[%zu], weightSize[%zu]",
        modelSize, workSize, weightSize);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(model);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelId);
    bool isSupportRT2 = false;
    ACL_REQUIRES_OK(acl::IsSupportRuntimeV2WithModelData(model, modelSize, isSupportRT2));
    aclError ret = ACL_SUCCESS;
    if (isSupportRT2) {
        ret = acl::RuntimeV2ModelLoadFromMemWithMem(model, modelSize, "", modelId,
                                                    weightPtr, weightSize, nullptr, 0);
    } else {
        ret = acl::ModelLoadFromMemWithMem(model, modelSize, "", modelId, workPtr,
                                           workSize, weightPtr, weightSize, nullptr, 0);
    }
    if (ret != ACL_SUCCESS) {
        return ret;
    }
    ACL_ADD_APPLY_SUCCESS_COUNT(acl::ACL_STATISTICS_CREATE_LOAD_UNLOAD_MODEL);
    ACL_LOG_INFO("successfully execute aclmdlLoadFromMemWithMem, modelSize[%zu], workSize[%zu], weightSize[%zu]",
        modelSize, workSize, weightSize);
    return ACL_SUCCESS;
}

aclError aclmdlLoadFromFileWithQ(const char *modelPath, uint32_t *modelId, const uint32_t *inputQ,
                                 size_t inputQNum, const uint32_t *outputQ, size_t outputQNum)
{
    ACL_PROFILING_REG(acl::AclProfType::AclmdlLoadFromFileWithQ);
    ACL_STAGES_REG(acl::ACL_STAGE_LOAD, acl::ACL_STAGE_DEFAULT);
    ACL_ADD_APPLY_TOTAL_COUNT(acl::ACL_STATISTICS_CREATE_LOAD_UNLOAD_MODEL);
    ACL_LOG_INFO("start to execute aclmdlLoadFromFileWithQ, inputQNum[%zu], outputQNum[%zu]", inputQNum, outputQNum);
    const aclError ret = acl::ModelLoadFromFileWithQ(modelPath, modelId, inputQ, inputQNum, outputQ, outputQNum, 0);
    if (ret != ACL_SUCCESS) {
        return ret;
    }
    ACL_ADD_APPLY_SUCCESS_COUNT(acl::ACL_STATISTICS_CREATE_LOAD_UNLOAD_MODEL);
    ACL_LOG_INFO("successfully execute aclmdlLoadFromFileWithQ, inputQNum[%zu], outputQNum[%zu]",
        inputQNum, outputQNum);
    return ACL_SUCCESS;
}

aclError aclmdlLoadFromMemWithQ(const void *model, size_t modelSize, uint32_t *modelId,
    const uint32_t *inputQ, size_t inputQNum, const uint32_t *outputQ, size_t outputQNum)
{
    ACL_PROFILING_REG(acl::AclProfType::AclmdlLoadFromMemWithQ);
    ACL_STAGES_REG(acl::ACL_STAGE_LOAD, acl::ACL_STAGE_DEFAULT);
    ACL_ADD_APPLY_TOTAL_COUNT(acl::ACL_STATISTICS_CREATE_LOAD_UNLOAD_MODEL);
    ACL_LOG_INFO("start to execute aclmdlLoadFromMemWithQ, modelSize[%zu], inputQNum[%zu], outputQNum[%zu]",
        modelSize, inputQNum, outputQNum);
    const aclError ret = acl::ModelLoadFromMemWithQ(model, modelSize, modelId,
        inputQ, inputQNum, outputQ, outputQNum, 0);
    if (ret != ACL_SUCCESS) {
        return ret;
    }
    ACL_ADD_APPLY_SUCCESS_COUNT(acl::ACL_STATISTICS_CREATE_LOAD_UNLOAD_MODEL);
    ACL_LOG_INFO("successfully execute aclmdlLoadFromMemWithQ, modelSize[%zu], inputQNum[%zu], outputQNum[%zu]",
        modelSize, inputQNum, outputQNum);
    return ACL_SUCCESS;
}

aclError aclmdlExecute(uint32_t modelId, const aclmdlDataset *input, aclmdlDataset *output)
{
    ACL_PROFILING_REG(acl::AclProfType::AclmdlExecute);
    ACL_STAGES_REG(acl::ACL_STAGE_EXEC, acl::ACL_STAGE_DEFAULT);
    ACL_LOG_INFO("start to execute aclmdlExecute, modelId[%u]", modelId);
    aclError ret = ACL_SUCCESS;
    if ((acl::AclResourceManager::GetInstance().IsRuntimeV2Enable(true)) &&
        (acl::AclResourceManager::GetInstance().GetExecutor(modelId) != nullptr)) {
        ret = acl::RuntimeV2ModelExecute(modelId, input, output, false, nullptr);
    } else {
        ret = acl::ModelExecute(modelId, input, output, false, nullptr);
    }
    if (ret == ACL_SUCCESS) {
        ACL_LOG_INFO("aclmdlExecute success, modelId[%u]", modelId);
    } else {
        ACL_LOG_INNER_ERROR("[Exec][Model]modelId[%u] execute failed, result[%d]", modelId, ret);
    }
    return ret;
}

aclError aclmdlExecuteV2(uint32_t modelId, const aclmdlDataset *input, aclmdlDataset *output, aclrtStream stream,
                         const aclmdlExecConfigHandle *handle)
{
    ACL_STAGES_REG(acl::ACL_STAGE_EXEC, acl::ACL_STAGE_DEFAULT);
    ACL_LOG_INFO("start to execute aclmdlExecuteV2, modelId[%u]", modelId);

    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(handle);
    if (handle->streamSyncTimeout >= DEFAULT_SYNC_TIMEOUT) {
        ACL_LOG_INFO("stream synchronize timeout = %d", handle->streamSyncTimeout);
        ge::GetContext().SetStreamSyncTimeout(handle->streamSyncTimeout);
    }
    if (handle->eventSyncTimeout >= DEFAULT_SYNC_TIMEOUT) {
        ACL_LOG_INFO("event synchronize timeout = %d", handle->eventSyncTimeout);
        ge::GetContext().SetEventSyncTimeout(handle->eventSyncTimeout);
    }

    aclError ret = ACL_SUCCESS;
    if ((acl::AclResourceManager::GetInstance().IsRuntimeV2Enable(true)) &&
        (acl::AclResourceManager::GetInstance().GetExecutor(modelId) != nullptr)) {
        ret = acl::RuntimeV2ModelExecute(modelId, input, output, false, stream);
    } else {
        ret = acl::ModelExecute(modelId, input, output, false, stream);
        if (stream != nullptr) {
            const rtError_t rtErr = rtStreamSynchronizeWithTimeout(static_cast<rtStream_t>(stream),
                                                                   handle->streamSyncTimeout);
            if (rtErr != RT_ERROR_NONE) {
                ACL_LOG_CALL_ERROR("synchronize stream failed, runtime result = %d", static_cast<int32_t>(rtErr));
                return ACL_GET_ERRCODE_RTS(rtErr);
            }
        }
    }
    if (ret == ACL_SUCCESS) {
        ACL_LOG_INFO("aclmdlExecuteV2 success, modelId[%u]", modelId);
    } else {
        ACL_LOG_INNER_ERROR("[Exec][Model]modelId[%u] execute failed, result[%d]", modelId, ret);
    }
    return ret;
}

aclError aclmdlExecuteAsync(uint32_t modelId, const aclmdlDataset *input,
                            aclmdlDataset *output, aclrtStream stream)
{
    ACL_PROFILING_REG(acl::AclProfType::AclmdlExecuteAsync);
    ACL_STAGES_REG(acl::ACL_STAGE_EXEC, acl::ACL_STAGE_DEFAULT);
    ACL_LOG_INFO("start to execute aclmdlExecuteAsync, modelId[%u]", modelId);

    aclError ret = ACL_SUCCESS;
    if ((acl::AclResourceManager::GetInstance().IsRuntimeV2Enable(true)) &&
        (acl::AclResourceManager::GetInstance().GetExecutor(modelId) != nullptr)) {
        ret = acl::RuntimeV2ModelExecute(modelId, input, output, true, stream);
    } else {
        ret = acl::ModelExecute(modelId, input, output, true, stream);
    }
    if (ret == ACL_SUCCESS) {
        ACL_LOG_INFO("aclmdlExecuteAsync success, modelId[%u]", modelId);
    } else {
        ACL_LOG_INNER_ERROR("[Exec][Model]aclmdlExecuteAsync failed, result[%d], modelId[%u]", ret, modelId);
    }
    return ret;
}

aclError aclmdlUnload(uint32_t modelId)
{
    ACL_PROFILING_REG(acl::AclProfType::AclmdlUnload);
    ACL_STAGES_REG(acl::ACL_STAGE_UNLOAD, acl::ACL_STAGE_DEFAULT);
    ACL_ADD_RELEASE_TOTAL_COUNT(acl::ACL_STATISTICS_CREATE_LOAD_UNLOAD_MODEL);
    ACL_LOG_INFO("start to execute aclmdlUnload, modelId[%u]", modelId);
    if (acl::AclResourceManager::GetInstance().IsBundleInnerId(modelId)) {
      ACL_LOG_ERROR("this modeId %u is bundle inner modelId, please ues aclmdlBundleUnload api instead", modelId);
      return ACL_ERROR_INVALID_PARAM;
    }
    ACL_REQUIRES_OK(UnloadModelInner(modelId));
    ACL_LOG_INFO("aclmdlUnload success, modelId[%u]", modelId);
    ACL_ADD_RELEASE_SUCCESS_COUNT(acl::ACL_STATISTICS_CREATE_LOAD_UNLOAD_MODEL);
    return ACL_SUCCESS;
}

aclError aclmdlBundleUnload(uint32_t bundleId)
{
    ACL_PROFILING_REG(acl::AclProfType::AclmdlBundleUnload);
    ACL_STAGES_REG(acl::ACL_STAGE_UNLOAD, acl::ACL_STAGE_DEFAULT);
    ACL_ADD_RELEASE_TOTAL_COUNT(acl::ACL_STATISTICS_CREATE_LOAD_UNLOAD_MODEL);
    ACL_LOG_INFO("start to execute aclmdlBundleUnload %u", bundleId);
    std::vector<acl::BundleInfo> bundleInfos;
    ACL_REQUIRES_OK(acl::AclResourceManager::GetInstance().GetBundleInfo(bundleId, bundleInfos));
    aclError finalRet = ACL_SUCCESS;
    for (auto &bundleInfo: bundleInfos) {
        // unload all and check result
        const auto ret = UnloadModelInner(bundleInfo.modelId);
        if (ret != ACL_SUCCESS) {
            finalRet = ret;
        }
    }
    ACL_REQUIRES_OK(finalRet);
    acl::AclResourceManager::GetInstance().DeleteBundleInfo(bundleId);
    // release session var manager
    ACL_REQUIRES_OK(acl::AclResourceManager::GetInstance().DeleteExecutor(bundleId));
    ACL_LOG_INFO("end to execute aclmdlBundleUnload %u", bundleId);
    ACL_ADD_RELEASE_SUCCESS_COUNT(acl::ACL_STATISTICS_CREATE_LOAD_UNLOAD_MODEL);
    return ACL_SUCCESS;
}

aclError aclmdlQuerySize(const char *fileName, size_t *workSize, size_t *weightSize)
{
    ACL_PROFILING_REG(acl::AclProfType::AclmdlQuerySize);
    ACL_STAGES_REG(acl::ACL_STAGE_GET, acl::ACL_STAGE_DEFAULT);
    ACL_LOG_INFO("start to execute aclmdlQuerySize");
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(fileName);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(workSize);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(weightSize);

    ge::GeExecutor executor;
    const std::string path(fileName);
    size_t work;
    size_t weight;
    ACL_LOG_DEBUG("call ge interface executor.GetMemAndWeightSize");
    const ge::Status ret = executor.GetMemAndWeightSize(path, work, weight);
    if (ret != ge::SUCCESS) {
        ACL_LOG_CALL_ERROR("[Get][MemAndWeightSize]query size failed, ge result[%u]", ret);
        return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
    }

    *workSize = work;
    *weightSize = weight;
    ACL_LOG_INFO("success to get size from file[%s], work size[%zu] bytes, weight size[%zu] bytes",
        fileName, *workSize, *weightSize);

    return ACL_SUCCESS;
}

aclError aclmdlQuerySizeFromMem(const void *model, size_t modelSize, size_t *workSize, size_t *weightSize)
{
    ACL_PROFILING_REG(acl::AclProfType::AclmdlQuerySizeFromMem);
    ACL_STAGES_REG(acl::ACL_STAGE_GET, acl::ACL_STAGE_DEFAULT);
    ACL_LOG_INFO("start to execute ACL_QueryModelSizeFromMem, modelSize[%zu]", modelSize);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(model);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(workSize);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(weightSize);

    ge::GeExecutor executor;
    size_t work;
    size_t weight;
    ACL_LOG_DEBUG("call ge interface executor.GetMemAndWeightSize, modelSize[%zu]", modelSize);
    const ge::Status ret = executor.GetMemAndWeightSize(model, modelSize, work, weight);
    if (ret != ge::SUCCESS) {
        ACL_LOG_CALL_ERROR("[Get][MemAndWeightSize]query size from mem failed, ge result[%u]", ret);
        return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
    }

    *workSize = work;
    *weightSize = weight;
    ACL_LOG_INFO("success to get size from mem, work size[%zu] bytes, weight size[%zu] bytes", *workSize,
        *weightSize);

    return ACL_SUCCESS;
}

aclError aclmdlSetDynamicBatchSize(uint32_t modelId, aclmdlDataset *dataset, size_t index, uint64_t batchSize)
{
    ACL_PROFILING_REG(acl::AclProfType::AclmdlSetDynamicBatchSize);
    ACL_LOG_INFO("start to execute aclmdlSetDynamicBatchSize, modelId[%u], index[%zu], batchSize[%lu]",
        modelId, index, batchSize);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dataset);

    if (batchSize == 0U) {
        ACL_LOG_INNER_ERROR("[Check][Batchsize]input param[batchSize] invalid, batchSize can't be zero");
        return ACL_ERROR_INVALID_PARAM;
    }

    const aclDataBuffer *const buf = aclmdlGetDatasetBuffer(dataset, index);
    if (buf == nullptr) {
        ACL_LOG_INNER_ERROR("[Check][buf]failed to get data buffer by index[%zu], dataset buffer is null", index);
        return ACL_ERROR_INVALID_PARAM;
    }

    void *const devPtr = aclGetDataBufferAddr(buf);
    if (devPtr == nullptr) {
        ACL_LOG_INNER_ERROR("[Check][devPtr]get addr by index[%zu] failed, data buffer addr can not be null", index);
        return ACL_ERROR_INVALID_PARAM;
    }
    const uint64_t memSize = aclGetDataBufferSizeV2(buf);

    dataset->dynamicBatchSize = batchSize;
    dataset->dynamicResolutionHeight = 0U;
    dataset->dynamicResolutionWidth = 0U;
    ACL_LOG_DEBUG("call ge interface executor.SetDynamicBatchSize, batchSize[%lu]", batchSize);
    ge::GeExecutor executor;
    const ge::Status ret = executor.SetDynamicBatchSize(modelId, devPtr, memSize, batchSize);
    if (ret != ge::SUCCESS) {
        ACL_LOG_CALL_ERROR("[Set][DynamicBatchSize]set DynamicBatchSize failed, ge result[%u]", ret);
        return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
    }

    ACL_LOG_INFO("successfully execute aclmdlSetDynamicBatchSize, modelId[%u], index[%zu], batchSize[%lu]",
        modelId, index, batchSize);
    return ACL_SUCCESS;
}

aclError aclmdlSetDynamicHWSize(uint32_t modelId, aclmdlDataset *dataset, size_t index,
    uint64_t height, uint64_t width)
{
    ACL_PROFILING_REG(acl::AclProfType::AclmdlSetDynamicHWSize);
    ACL_LOG_INFO("start to execute aclmdlSetDynamicHWSize, modelId[%u], index[%zu], height[%lu], width[%lu]",
        modelId, index, height, width);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dataset);

    if ((height == 0U) || (width == 0U)) {
        ACL_LOG_INNER_ERROR("[Check][Params]height[%lu] or width[%lu] is invalid, can't be zero.", height, width);
        return ACL_ERROR_INVALID_PARAM;
    }

    aclDataBuffer *const buffer = aclmdlGetDatasetBuffer(dataset, index);
    if (buffer == nullptr) {
        ACL_LOG_INNER_ERROR("[Check][buffer]get data buffer by index[%zu] failed, dataset buffer can not be null",
            index);
        return ACL_ERROR_INVALID_PARAM;
    }

    void *const devPtr = aclGetDataBufferAddr(buffer);
    if (devPtr == nullptr) {
        ACL_LOG_INNER_ERROR("[Check][devPtr]get addr by index[%zu] failed, data buffer addr can not be nullptr", index);
        return ACL_ERROR_INVALID_PARAM;
    }
    const uint64_t memSize = aclGetDataBufferSizeV2(buffer);

    dataset->dynamicBatchSize = 0U;
    dataset->dynamicResolutionHeight = height;
    dataset->dynamicResolutionWidth = width;
    ACL_LOG_DEBUG("call ge interface executor.SetDynamicImageSize, height[%lu],width[%lu]", height, width);
    ge::GeExecutor executor;
    const ge::Status ret = executor.SetDynamicImageSize(modelId, devPtr, memSize, height, width);
    if (ret != ge::SUCCESS) {
        ACL_LOG_CALL_ERROR("[Set][DynamicImageSize]Set dynamic image size, ge result[%u]", ret);
        return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
    }

    ACL_LOG_INFO("successfully execute aclmdlSetDynamicHWSize, modelId[%u], index[%zu], height[%lu], width[%lu]",
        modelId, index, height, width);
    return ACL_SUCCESS;
}

aclError aclmdlSetInputDynamicDims(uint32_t modelId, aclmdlDataset *dataset, size_t index, const aclmdlIODims *dims)
{
    ACL_PROFILING_REG(acl::AclProfType::AclmdlSetInputDynamicDims);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dataset);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dims);
    if (dims->dimCount == 0U) {
        ACL_LOG_ERROR("[Check][dimCount]dimCount[%zu] is invalid, can't be zero.", dims->dimCount);
        const std::string errMsg = acl::AclErrorLogManager::FormatStr("dimCount[%u] can't be zero", dims->dimCount);
        acl::AclErrorLogManager::ReportInputError(acl::INVALID_PARAM_MSG,
            std::vector<std::string>({"param", "value", "reason"}),
            std::vector<std::string>({"dimCount", "0", errMsg}));
        return ACL_ERROR_INVALID_PARAM;
    }

    ACL_LOG_INFO("start to execute aclmdlSetInputDynamicDims, modelId[%u], index[%zu], dimCount[%zu]",
                 modelId, index, dims->dimCount);
    aclDataBuffer *const buffer = aclmdlGetDatasetBuffer(dataset, index);
    ACL_CHECK_WITH_INNER_MESSAGE_AND_RETURN(buffer != nullptr, ACL_ERROR_INVALID_PARAM,
        "[Check][buffer]get data buffer by index[%zu] failed, dataset buffer can not be null", index);

    void *const devPtr = aclGetDataBufferAddr(buffer);
    ACL_CHECK_WITH_INNER_MESSAGE_AND_RETURN(devPtr != nullptr, ACL_ERROR_INVALID_PARAM,
        "[Get][devPtr]get addr by index[%zu] failed, data buffer addr can not be null", index);
    const uint64_t memSize = aclGetDataBufferSizeV2(buffer);

    dataset->dynamicBatchSize = 0U;
    dataset->dynamicResolutionHeight = 0U;
    dataset->dynamicResolutionWidth = 0U;
    dataset->dynamicDims.clear();
    std::vector<uint64_t> curAllDims;
    for (size_t i = 0U; i < static_cast<std::size_t>(dims->dimCount); ++i) {
        curAllDims.push_back(static_cast<size_t>(dims->dims[i]));
    }
    ACL_LOG_DEBUG("Call ge interface executor.SetDynamicDims, dimCount[%zu]", dims->dimCount);
    ACL_LOG_DEBUG("Cur all dims size %zu", curAllDims.size());
    ge::GeExecutor executor;
    ge::Status ret = executor.SetDynamicDims(modelId, devPtr, memSize, curAllDims);
    if (ret != ge::SUCCESS) {
        ACL_LOG_CALL_ERROR("[Set][DynamicDims]set dynamic dims failed, ge result[%u]", ret);
        return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
    }

    std::vector<uint64_t> curDynmaicDims;
    ret = executor.GetCurDynamicDims(modelId, curAllDims, curDynmaicDims);
    if (ret != ge::SUCCESS) {
        ACL_LOG_CALL_ERROR("[Get][CurDynamicDims]get current dynamic dims failed, ge result[%u]", ret);
        return ACL_GET_ERRCODE_GE(static_cast<int32_t>(ret));
    }
    ACL_LOG_DEBUG("current dynamic dims size %zu", curDynmaicDims.size());
    dataset->dynamicDims = curDynmaicDims;

    ACL_LOG_INFO("successfully execute aclmdlSetInputDynamicDims, modelId[%u], index[%zu], dimCount[%zu]",
                 modelId, index, dims->dimCount);
    return ACL_SUCCESS;
}

aclError aclmdlGetInputDims(const aclmdlDesc *modelDesc, size_t index, aclmdlIODims *dims)
{
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelDesc);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dims);

    const aclError ret = acl::GetDims(modelDesc, TensorType::INPUT_TENSOR_TYPE, DimsType::DIMS_TYPE_V1, index, dims);
    if (ret != ACL_SUCCESS) {
        ACL_LOG_INNER_ERROR("[Get][Dims]get input dims failed, result[%d], index[%zu], modelId[%u]", ret, index,
            modelDesc->modelId);
    }

    return ret;
}

aclError aclmdlGetOutputDims(const aclmdlDesc *modelDesc, size_t index, aclmdlIODims *dims)
{
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelDesc);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dims);

    const aclError ret = acl::GetDims(modelDesc, TensorType::OUTPUT_TENSOR_TYPE, DimsType::DIMS_TYPE_V1, index, dims);
    if (ret != ACL_SUCCESS) {
        ACL_LOG_INNER_ERROR("[Get][Dims]get output dims failed, result[%d], index[%zu], modelId[%u]",
            ret, index, modelDesc->modelId);
    }

    return ret;
}

aclError aclmdlGetInputDimsV2(const aclmdlDesc *modelDesc, size_t index, aclmdlIODims *dims)
{
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelDesc);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dims);

    const aclError ret = acl::GetDims(modelDesc, TensorType::INPUT_TENSOR_TYPE, DimsType::DIMS_TYPE_V2, index, dims);
    if (ret != ACL_SUCCESS) {
        ACL_LOG_INNER_ERROR("[Get][Dims]get input dims(v2) failed, result[%d], index[%zu], modelId[%u]",
            ret, index, modelDesc->modelId);
    }

    return ret;
}

aclError aclmdlGetInputDimsRange(const aclmdlDesc *modelDesc, size_t index, aclmdlIODimsRange *dimsRange)
{
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelDesc);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dimsRange);

    const aclError ret = acl::GetDimsRange(modelDesc, TensorType::INPUT_TENSOR_TYPE, index, dimsRange);
    if (ret != ACL_SUCCESS) {
        ACL_LOG_INNER_ERROR("[Get][DimsRange]get input dims range failed, result[%d], index[%zu], modelId[%u]",
            ret, index, modelDesc->modelId);
    }

    return ret;
}

aclError aclmdlGetCurOutputDims(const aclmdlDesc *modelDesc, size_t index, aclmdlIODims *dims)
{
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelDesc);
    if (acl::AclResourceManager::GetInstance().IsRuntimeV2Enable(true) &&
        (acl::AclResourceManager::GetInstance().GetExecutor(modelDesc->modelId) != nullptr)) {
        ACL_LOG_WARN("This api does not support dynamic model, please check.");
        return ACL_ERROR_API_NOT_SUPPORT;
    }
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dims);
    const uint32_t modelId = modelDesc->modelId;
    const size_t descSize = modelDesc->outputDesc.size();
    ACL_CHECK_WITH_INNER_MESSAGE_AND_RETURN(index < descSize, ACL_ERROR_INVALID_PARAM,
        "[Check][descSize]aclmdlGetCurOutputDims failed, index[%zu] should be smaller "
        "than tensor size[%zu], modelId[%u]", index, descSize, modelId);

    std::vector<int64_t> geShapeInfo;
    ge::GeExecutor executor;
    int32_t dynamicType = static_cast<int32_t>(ge::FIXED);
    const ge::Status geRet = executor.GetCurShape(modelId, geShapeInfo, dynamicType);
    if (geRet != ge::SUCCESS) {
        ACL_LOG_CALL_ERROR("[Get][CurShape]can not get current shape, ge result[%d], modelId[%u]", geRet, modelId);
        return ACL_GET_ERRCODE_GE(static_cast<int32_t>(geRet));
    }
    // dynamic batch type is 1, dynamic hw type is 2, dynamic dims type is 3;
    // static model or not set dynamic shape info, dynamic type is 0, other value is invalid
    aclError aclRet;
    const size_t shapeSize = geShapeInfo.size();
    if ((dynamicType != static_cast<int32_t>(ge::DYNAMIC_DIMS)) && (shapeSize > 2U)) {
        ACL_LOG_INNER_ERROR("[Check][dynamicType]shapeSize[%zu] is invalid, modelId[%u]", shapeSize, modelId);
        return ACL_ERROR_GE_FAILURE;
    }
    if (shapeSize == 0U) {
        ACL_LOG_DEBUG("Dynamic type is 0, model[%u] is static or not set dynamic shape info", modelId);
        aclRet = acl::GetDims(modelDesc, TensorType::OUTPUT_TENSOR_TYPE, DimsType::DIMS_TYPE_V1, index, dims);
        ACL_REQUIRES_OK_WITH_INNER_MESSAGE(aclRet,
            "[Get][Dims]get current output dims failed, result[%d], index[%zu], modelId[%u]",
            aclRet, index, modelId);
        return ACL_SUCCESS;
    }

    size_t curGearIndex = 0U;
    std::vector<uint64_t> shapeInfo;
    for (auto &it : geShapeInfo) {
        shapeInfo.emplace_back(static_cast<uint64_t>(it));
    }
    aclRet = acl::GetCurGearIndex(modelDesc, shapeInfo, dynamicType, curGearIndex);
    ACL_REQUIRES_OK_WITH_INNER_MESSAGE(aclRet,
        "[Get][CurGearIndex]get current gear index failed, result[%d], index[%zu], "
        "modelId[%u], dynamicBatchSize[%zu], dynamicHWSize[%zu]", aclRet, index, modelId,
        modelDesc->dynamicBatch.size(), modelDesc->dynamicHW.size());

    aclRet = acl::GetCurOuputShapeInfo(modelDesc, index, curGearIndex, dims);
    ACL_REQUIRES_OK_WITH_INNER_MESSAGE(aclRet,
        "[Get][CurOuputShapeInfo]get current output shape info failed, result[%d], "
        "index[%zu], modelId[%u], the size of dynamicOutputShape[%zu]", aclRet, index, modelId,
        modelDesc->dynamicOutputShape.size());

    return ACL_SUCCESS;
}

const char *aclmdlGetOpAttr(aclmdlDesc *modelDesc, const char *opName, const char *attr)
{
    ACL_LOG_INFO("start to execute aclmdlGetOpAttr");
    ACL_REQUIRES_NOT_NULL_RET_NULL(modelDesc);
    ACL_REQUIRES_NOT_NULL_RET_NULL(opName);
    ACL_REQUIRES_NOT_NULL_RET_NULL(attr);

    const std::string opNameStr(opName);
    const std::string attrStr(attr);
    if (attrStr != ACL_ATTR_NAME_DATA_DUMP_ORIGIN_OP_NAMES) {
        ACL_LOG_INNER_ERROR("failed to execute aclmdlGetOpAttr, attr[%s] is invalid, only support "
            "ACL_ATTR_NAME_DATA_DUMP_ORIGIN_OP_NAMES", attrStr.c_str());
        return nullptr;
    }

    const std::unique_lock<std::mutex> lock(aclmdlGetOpAttrMutex);
    std::map<std::string, std::map<std::string, std::string>>::const_iterator itOpName =
        modelDesc->opAttrValueMap.find(opName);
    if (itOpName != modelDesc->opAttrValueMap.cend()) {
        std::map<std::string, std::string>::const_iterator itAttr = itOpName->second.find(attr);
        if (itAttr != itOpName->second.cend()) {
            ACL_LOG_INFO("opName is [%s], the value of attr [%s] is %s", opName, attr, itAttr->second.c_str());
            return itAttr->second.c_str();
        }
    }

    ge::GeExecutor executor;
    const uint32_t modelId = modelDesc->modelId;
    ACL_LOG_INFO("Call ge interface executor.GetOpAttr, modelId is [%u], opName is [%s], attr is [%s]",
        modelId, opName, attr);
    std::string attrValue;
    const ge::Status ret = executor.GetOpAttr(modelId, opNameStr, attrStr, attrValue);
    if (ret != ge::SUCCESS) {
        ACL_LOG_CALL_ERROR("[Get][Opattr]Execute GetOpAttr failed, ge result[%u], modelId[%u]", ret, modelId);
        return nullptr;
    }
    ACL_LOG_INFO("Execute aclmdlGetOpAttr successfully, opName is [%s], the value of attr[%s] is %s", opName, attr,
        attrValue.c_str());
    modelDesc->opAttrValueMap[opNameStr][attrStr] = attrValue;
    return modelDesc->opAttrValueMap[opNameStr][attrStr].c_str();
}

const char *aclmdlGetInputNameByIndex(const aclmdlDesc *modelDesc, size_t index)
{
    ACL_LOG_INFO("start to execute aclmdlGetInputNameByIndex");
    if (modelDesc == nullptr) {
        ACL_LOG_ERROR("[Check][ModelDesc]modelDesc is null");
        acl::AclErrorLogManager::ReportInputError(acl::INVALID_NULL_POINTER_MSG,
            std::vector<std::string>({"param"}),
            std::vector<std::string>({"modelDesc"}));
        return "";
    }

    return acl::aclmdlGetNameByIndex(modelDesc->inputDesc, index);
}

const char *aclmdlGetOutputNameByIndex(const aclmdlDesc *modelDesc, size_t index)
{
    ACL_LOG_INFO("start to execute aclmdlGetOutputNameByIndex");
    if (modelDesc == nullptr) {
        ACL_LOG_ERROR("[Check][ModelDesc]modelDesc is null");
        acl::AclErrorLogManager::ReportInputError(acl::INVALID_NULL_POINTER_MSG,
            std::vector<std::string>({"param"}),
            std::vector<std::string>({"modelDesc"}));
        return "";
    }

    return acl::aclmdlGetNameByIndex(modelDesc->outputDesc, index);
}

aclFormat aclmdlGetInputFormat(const aclmdlDesc *modelDesc, size_t index)
{
    ACL_LOG_INFO("start to execute aclmdlGetInputFormat");
    if (modelDesc == nullptr) {
        ACL_LOG_ERROR("[Check][ModelDesc]modelDesc is null");
        acl::AclErrorLogManager::ReportInputError(acl::INVALID_NULL_POINTER_MSG,
            std::vector<std::string>({"param"}),
            std::vector<std::string>({"modelDesc"}));
        return ACL_FORMAT_UNDEFINED;
    }

    return acl::aclmdlGetFormat(modelDesc->inputDesc, index);
}

aclFormat aclmdlGetOutputFormat(const aclmdlDesc *modelDesc, size_t index)
{
    ACL_LOG_INFO("start to execute aclmdlGetOutputFormat");
    if (modelDesc == nullptr) {
        ACL_LOG_ERROR("[Check][ModelDesc]modelDesc is null");
        acl::AclErrorLogManager::ReportInputError(acl::INVALID_NULL_POINTER_MSG,
            std::vector<std::string>({"params"}),
            std::vector<std::string>({"modelDesc"}));
        return ACL_FORMAT_UNDEFINED;
    }

    return acl::aclmdlGetFormat(modelDesc->outputDesc, index);
}

aclDataType aclmdlGetInputDataType(const aclmdlDesc *modelDesc, size_t index)
{
    ACL_LOG_INFO("start to execute aclmdlGetInputDataType");
    if (modelDesc == nullptr) {
        ACL_LOG_ERROR("[Check][ModelDesc]modelDesc is null");
        acl::AclErrorLogManager::ReportInputError(acl::INVALID_NULL_POINTER_MSG,
            std::vector<std::string>({"param"}), std::vector<std::string>({"modelDesc"}));
        return ACL_DT_UNDEFINED;
    }

    return acl::aclmdlGetDataType(modelDesc->inputDesc, index);
}

aclDataType aclmdlGetOutputDataType(const aclmdlDesc *modelDesc, size_t index)
{
    ACL_LOG_INFO("start to execute aclmdlGetOutputDataType");
    if (modelDesc == nullptr) {
        ACL_LOG_ERROR("[Check][ModelDesc]modelDesc is null");
        acl::AclErrorLogManager::ReportInputError(acl::INVALID_NULL_POINTER_MSG,
            std::vector<std::string>({"param"}),
            std::vector<std::string>({"modelDesc"}));
        return ACL_DT_UNDEFINED;
    }

    return acl::aclmdlGetDataType(modelDesc->outputDesc, index);
}

aclError aclmdlGetInputIndexByName(const aclmdlDesc *modelDesc, const char *name, size_t *index)
{
    ACL_LOG_INFO("start to execute aclmdlGetInputIndexByName");
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelDesc);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(name);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(index);

    ACL_LOG_INFO("successfully execute aclmdlGetInputIndexByName");
    return acl::aclmdlGetIndexByName(modelDesc->inputDesc, name, index);
}

aclError aclmdlGetOutputIndexByName(const aclmdlDesc *modelDesc, const char *name, size_t *index)
{
    ACL_LOG_INFO("start to execute aclmdlGetOutputIndexByName");
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelDesc);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(name);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(index);

    ACL_LOG_INFO("successfully execute aclmdlGetOutputIndexByName");
    return acl::aclmdlGetIndexByName(modelDesc->outputDesc, name, index);
}

aclError aclmdlGetDynamicBatch(const aclmdlDesc *modelDesc, aclmdlBatch *batch)
{
    ACL_LOG_INFO("start to execute aclmdlGetDynamicBatch");
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelDesc);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(batch);

    const size_t batchCnt = modelDesc->dynamicBatch.size();
    if (batchCnt > static_cast<size_t>(ACL_MAX_BATCH_NUM)) {
        ACL_LOG_ERROR("[Check][batchCnt]aclmdlGetBatch failed, batch count[%zu] is larger than max batch num[%d]",
            batchCnt, ACL_MAX_BATCH_NUM);
        const std::string errMsg =
            acl::AclErrorLogManager::FormatStr("batch count[%zu] is larger than max batch num[%d]",
                batchCnt, ACL_MAX_BATCH_NUM);
        acl::AclErrorLogManager::ReportInputError(acl::INVALID_PARAM_MSG,
            std::vector<std::string>({"param", "value", "reason"}),
            std::vector<std::string>({"batch count", std::to_string(batchCnt), errMsg}));
        return ACL_ERROR_STORAGE_OVER_LIMIT;
    }

    batch->batchCount = batchCnt;
    if (batchCnt == 0U) {
        ACL_LOG_INFO("batch count is 0");
        return ACL_SUCCESS;
    }

    for (size_t i = 0U; i < batchCnt; ++i) {
        batch->batch[i] = modelDesc->dynamicBatch[i];
    }

    ACL_LOG_INFO("successfully execute aclmdlGetDynamicBatch");
    return ACL_SUCCESS;
}

aclError aclmdlGetDynamicHW(const aclmdlDesc *modelDesc, size_t index, aclmdlHW *hw)
{
    (void)index;
    ACL_LOG_INFO("start to execute aclmdlGetDynamicHW");
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelDesc);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(hw);

    const size_t hwCnt = modelDesc->dynamicHW.size();
    if (hwCnt > static_cast<size_t>(ACL_MAX_HW_NUM)) {
        ACL_LOG_INNER_ERROR("[Check][hwCnt]aclmdlGetHW failed, hw count[%zu] is larger than max[%d]",
            hwCnt, ACL_MAX_HW_NUM);
        return ACL_ERROR_STORAGE_OVER_LIMIT;
    }

    hw->hwCount = hwCnt;
    if (hwCnt == 0U) {
        ACL_LOG_INFO("hw count is 0");
        return ACL_SUCCESS;
    }

    for (size_t i = 0U; i < hwCnt; ++i) {
        for (size_t j = 0U; j < 2U; ++j) { // dynamic hw,size is 2
            hw->hw[i][j] = modelDesc->dynamicHW[i][j];
        }
    }
    ACL_LOG_INFO("successfully execute aclmdlGetDynamicHW");
    return ACL_SUCCESS;
}

aclError aclmdlGetInputDynamicGearCount(const aclmdlDesc *modelDesc, size_t index, size_t *gearCount)
{
    ACL_LOG_INFO("start to execute aclmdlGetInputDynamicGearCount");
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelDesc);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(gearCount);

    if (index != static_cast<size_t>(-1)) {
        ACL_LOG_INNER_ERROR("[Check][index]aclmdlGetInputDynamicGearCount failed, index must be -1 while input is %zu.",
            index);
        return ACL_ERROR_INVALID_PARAM;
    }

    const size_t dimCnt = modelDesc->dynamicDims.size();
    if (dimCnt > static_cast<size_t>(ACL_MAX_DIM_CNT)) {
        ACL_LOG_INNER_ERROR("[Check][dimCnt]aclmdlGetInputDynamicGearCount failed, dimCnt[%zu] is "
            "larger than max[%d]", dimCnt, ACL_MAX_DIM_CNT);
        return ACL_ERROR_STORAGE_OVER_LIMIT;
    }

    if (dimCnt == 0U) {
        *gearCount = 0U;
        ACL_LOG_INFO("Gear count is 0");
        return ACL_SUCCESS;
    }
    *gearCount = dimCnt;
    ACL_LOG_INFO("successfully execute aclmdlGetInputDynamicGearCount");
    return ACL_SUCCESS;
}

aclError aclmdlGetInputDynamicDims(const aclmdlDesc *modelDesc, size_t index, aclmdlIODims *dims, size_t gearCount)
{
    ACL_LOG_INFO("start to execute aclmdlGetInputDynamicDims");
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelDesc);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dims);
    if (index != static_cast<std::size_t>(-1)) {
        ACL_LOG_INNER_ERROR("[Check][index]aclmdlGetInputDynamicDims failed, index must be -1 but it is %zu", index);
        return ACL_ERROR_INVALID_PARAM;
    }
    if (gearCount < modelDesc->dynamicDims.size()) {
        ACL_LOG_INNER_ERROR("[Check][gearCount]Gear count[%zu] can not less than model's dynamic gear count[%zu]",
            gearCount, modelDesc->dynamicDims.size());
        return ACL_ERROR_INVALID_PARAM;
    }
    std::vector<int64_t> allRawDims;
    for (auto &dataName : modelDesc->dataNameOrder) {
        for (auto &inputDesc : modelDesc->inputDesc) {
            if (inputDesc.name == dataName) {
                (void)allRawDims.insert(allRawDims.cend(), inputDesc.dims.cbegin(), inputDesc.dims.cend());
            }
        }
    }
    if (allRawDims.size() > ACL_MAX_DIM_CNT) {
        ACL_LOG_ERROR("current dynamic dims size %zu can not be larger than %d", allRawDims.size(), ACL_MAX_DIM_CNT);
        return ACL_ERROR_FAILURE;
    }

    for (size_t i = 0U; i < modelDesc->dynamicDims.size(); ++i) {
        size_t begIndex = 0U;
        for (size_t j = 0U; j < allRawDims.size(); ++j) {
            if (allRawDims[j] < 0) {
                if (begIndex >= modelDesc->dynamicDims[i].size()) {
                    ACL_LOG_INNER_ERROR("[Check][begIndex]User input data index[%zu] shape size overflow", index);
                    return ACL_ERROR_INVALID_PARAM;
                }
                dims[i].dims[j] = static_cast<int64_t>(modelDesc->dynamicDims[i][begIndex]);
                begIndex++;
            } else {
                dims[i].dims[j] = allRawDims[j];
            }
            dims[i].dimCount = allRawDims.size();
        }
    }
    ACL_LOG_INFO("successfully execute aclmdlGetInputDynamicDims");
    return ACL_SUCCESS;
}

aclError aclmdlCreateAndGetOpDesc(uint32_t deviceId, uint32_t streamId, uint32_t taskId, char *opName,
    size_t opNameLen, aclTensorDesc **inputDesc, size_t *numInputs, aclTensorDesc **outputDesc, size_t *numOutputs)
{
    ACL_LOG_INFO("start to execute aclmdlCreateAndGetOpDesc, deviceId[%u], streamId[%u], taskId[%u]",
        deviceId, streamId, taskId);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(opName);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(inputDesc);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(outputDesc);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(numInputs);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(numOutputs);

    ge::GeExecutor executor;
    ge::OpDescInfo opDescInfo;
    ACL_LOG_DEBUG("call ge interface executor.GetOpDescInfo");
    const ge::Status geRet = executor.GetOpDescInfo(deviceId, streamId, taskId, opDescInfo);
    if (geRet != ge::SUCCESS) {
        ACL_LOG_CALL_ERROR("[Get][OpDescInfo]get op desc faild, ge result[%d], deviceId[%u], streamId[%u], taskId[%u]",
            geRet, deviceId, streamId, taskId);
        return ACL_GET_ERRCODE_GE(static_cast<int32_t>(geRet));
    }

    if (opNameLen <= opDescInfo.op_name.length()) {
        ACL_LOG_INNER_ERROR("[Check][opNameLen]input length = %zu must be larger than op name real length = %zu",
            opNameLen, opDescInfo.op_name.length());
        return ACL_ERROR_INVALID_PARAM;
    }
    const auto ret = strncpy_s(opName, opNameLen, opDescInfo.op_name.c_str(),
        opDescInfo.op_name.length());
    if (ret != EOK) {
        ACL_LOG_INNER_ERROR("[Copy][OpName]copy op name failed, copy errorCode = %d, input opNameLen = %zu, "
            "real opNameLen = %zu", ret, opNameLen, opDescInfo.op_name.length());
        return ACL_ERROR_FAILURE;
    }

    const size_t inputNum = opDescInfo.input_format.size();
    const size_t outputNum = opDescInfo.output_format.size();

    ACL_REQUIRES_POSITIVE(inputNum);
    ACL_REQUIRES_POSITIVE(outputNum);
    *inputDesc = new(std::nothrow) aclTensorDesc[inputNum];
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(*inputDesc);
    *outputDesc = new(std::nothrow) aclTensorDesc[outputNum];
    if (*outputDesc == nullptr) {
        ACL_LOG_INNER_ERROR("[Check][outputDesc]alloc outputDesc memory failed");
        ACL_DELETE_ARRAY_AND_SET_NULL(*inputDesc);
        return ACL_ERROR_FAILURE;
    }
    ACL_REQUIRES_EQ(opDescInfo.input_data_type.size(), inputNum);
    ACL_REQUIRES_EQ(opDescInfo.input_shape.size(), inputNum);
    ACL_REQUIRES_EQ(opDescInfo.input_addrs.size(), inputNum);
    for (size_t idx = 0U; idx < inputNum; ++idx) {
        (*inputDesc)[idx].format = static_cast<aclFormat>(opDescInfo.input_format[idx]);
        (*inputDesc)[idx].dataType = static_cast<aclDataType>(opDescInfo.input_data_type[idx]);
        (*inputDesc)[idx].dims.assign(opDescInfo.input_shape[idx].begin(), opDescInfo.input_shape[idx].end());
        (*inputDesc)[idx].address = opDescInfo.input_addrs[idx];
    }
    ACL_REQUIRES_EQ(opDescInfo.output_data_type.size(), outputNum);
    ACL_REQUIRES_EQ(opDescInfo.output_shape.size(), outputNum);
    ACL_REQUIRES_EQ(opDescInfo.output_addrs.size(), outputNum);
    for (size_t idx = 0U; idx < outputNum; ++idx) {
        (*outputDesc)[idx].format = static_cast<aclFormat>(opDescInfo.output_format[idx]);
        (*outputDesc)[idx].dataType = static_cast<aclDataType>(opDescInfo.output_data_type[idx]);
        (*outputDesc)[idx].dims.assign(opDescInfo.output_shape[idx].begin(), opDescInfo.output_shape[idx].end());
        (*outputDesc)[idx].address = opDescInfo.output_addrs[idx];
    }
    *numInputs = inputNum;
    *numOutputs = outputNum;
    ACL_LOG_INFO("successfully execute aclmdlCreateAndGetOpDesc, deviceId[%u], streamId[%u], "
        "taskId[%u], numInputs[%zu], numOutputs[%zu]", deviceId, streamId, taskId, *numInputs, *numOutputs);
    return ACL_SUCCESS;
}

aclError aclmdlLoadWithConfig(const aclmdlConfigHandle *handle, uint32_t *modelId)
{
    ACL_PROFILING_REG(acl::AclProfType::AclmdlLoadWithConfig);
    ACL_STAGES_REG(acl::ACL_STAGE_LOAD, acl::ACL_STAGE_DEFAULT);
    ACL_ADD_APPLY_TOTAL_COUNT(acl::ACL_STATISTICS_CREATE_LOAD_UNLOAD_MODEL);
    ACL_LOG_INFO("start to execute aclmdlLoadWithConfig");
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(handle);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelId);
    if (!acl::CheckMdlConfigHandle(handle)) {
        ACL_LOG_INNER_ERROR("[Check][ConfigHandle]model config is invalid because some param may not be set");
        return ACL_ERROR_INVALID_PARAM;
    }
    acl::UpdateGraphOptions(OPTION_EXEC_REUSE_ZERO_COPY_MEMORY, std::to_string(handle->reuseZeroCopy));

    bool isSupportRT2 = false;
    switch (static_cast<int32_t>(handle->mdlLoadType)) {
        case ACL_MDL_LOAD_FROM_FILE:
        {
            ACL_REQUIRES_OK(acl::IsSupportRuntimeV2WithModelPath(handle->loadPath.c_str(), isSupportRT2));
            if (isSupportRT2) {
                return acl::RuntimeV2ModelLoadFromFileWithMem(handle->loadPath.c_str(), modelId, nullptr, 0U,
                                                              handle->priority);
            }
            return acl::ModelLoadFromFileWithMem(handle->loadPath.c_str(), modelId,
                                                 nullptr, 0U, nullptr, 0U, handle->priority);
        }
        case ACL_MDL_LOAD_FROM_FILE_WITH_MEM:
        {
            ACL_REQUIRES_OK(acl::IsSupportRuntimeV2WithModelPath(handle->loadPath.c_str(), isSupportRT2));
            if (isSupportRT2) {
                return acl::RuntimeV2ModelLoadFromFileWithMem(handle->loadPath.c_str(), modelId, handle->weightPtr,
                                                              handle->weightSize, handle->priority);
            }
            return acl::ModelLoadFromFileWithMem(handle->loadPath.c_str(), modelId, handle->workPtr,
                                                 handle->workSize, handle->weightPtr, handle->weightSize,
                                                 handle->priority);
        }
        case ACL_MDL_LOAD_FROM_MEM:
        {
            ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(handle->mdlAddr);
            ACL_REQUIRES_OK(acl::IsSupportRuntimeV2WithModelData(handle->mdlAddr, handle->mdlSize, isSupportRT2));
            if (isSupportRT2) {
                return acl::RuntimeV2ModelLoadFromMemWithMem(handle->mdlAddr, handle->mdlSize, "", modelId, nullptr, 0U,
                                                             handle->weightPath.c_str(), handle->priority);
            }
            return acl::ModelLoadFromMemWithMem(handle->mdlAddr, handle->mdlSize, "", modelId, nullptr, 0U, nullptr, 0U,
                                                handle->weightPath.c_str(), handle->priority);
        }
        case ACL_MDL_LOAD_FROM_MEM_WITH_MEM:
        {
            ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(handle->mdlAddr);
            ACL_REQUIRES_OK(acl::IsSupportRuntimeV2WithModelData(handle->mdlAddr, handle->mdlSize, isSupportRT2));
            if (isSupportRT2) {
                return acl::RuntimeV2ModelLoadFromMemWithMem(handle->mdlAddr, handle->mdlSize, "", modelId,
                                                             handle->weightPtr, handle->weightSize,
                                                             nullptr, handle->priority);
            }
            return acl::ModelLoadFromMemWithMem(handle->mdlAddr, handle->mdlSize, "", modelId, handle->workPtr,
                                                handle->workSize, handle->weightPtr, handle->weightSize,
                                                nullptr, handle->priority);
        }
        case ACL_MDL_LOAD_FROM_FILE_WITH_Q:
            return acl::ModelLoadFromFileWithQ(handle->loadPath.c_str(), modelId, handle->inputQ,
                handle->inputQNum, handle->outputQ, handle->outputQNum, handle->priority);
        case ACL_MDL_LOAD_FROM_MEM_WITH_Q:
            return acl::ModelLoadFromMemWithQ(handle->mdlAddr, handle->mdlSize, modelId,
                handle->inputQ, handle->inputQNum,
                handle->outputQ, handle->outputQNum, handle->priority);
        default:
            ACL_LOG_INNER_ERROR("[Load][Model]model load type[%zu] is invalid, it should be in [%d, %d]",
                handle->mdlLoadType, ACL_MDL_LOAD_FROM_FILE, ACL_MDL_LOAD_FROM_MEM_WITH_Q);
            return ACL_ERROR_INVALID_PARAM;
    }
}

const char *aclmdlGetTensorRealName(const aclmdlDesc *modelDesc, const char *name)
{
    ACL_LOG_INFO("start to execute aclmdlGetTensorName");
    ACL_REQUIRES_NOT_NULL_RET_NULL_INPUT_REPORT(modelDesc);
    ACL_REQUIRES_NOT_NULL_RET_NULL_INPUT_REPORT(name);
    const char_t *realTensorName = acl::GetRealTensorName(modelDesc, name);
    if (realTensorName != nullptr) {
        ACL_LOG_INFO("successfully execute aclmdlGetTensorName, realTensorName = %s", realTensorName);
        return realTensorName;
    }
    realTensorName = acl::TransTensorNameToReal(modelDesc, name);
    if (realTensorName != nullptr) {
        ACL_LOG_INFO("successfully execute aclmdlGetTensorName, realTensorName = %s", realTensorName);
        return realTensorName;
    }
    ACL_LOG_INNER_ERROR("[Get][TensorName]execute aclmdlGetTensorName failed, name[%s] is invalid.", name);
    return nullptr;
}

aclError aclmdlRIExecuteAsync(aclmdlRI modelRI, aclrtStream stream)
{
    ACL_PROFILING_REG(acl::AclProfType::AclmdlRIExecuteAsync);
    ACL_STAGES_REG(acl::ACL_STAGE_EXEC, acl::ACL_STAGE_DEFAULT);
    ACL_LOG_INFO("start to execute aclmdlRIExecuteAsync");
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelRI);
    const rtError_t rtErr = rtModelExecute(static_cast<rtModel_t>(modelRI), static_cast<rtStream_t>(stream), 0U);
    if (rtErr != RT_ERROR_NONE) {
        ACL_LOG_CALL_ERROR("execute rtModel failed, runtime result = %d", static_cast<int32_t>(rtErr));
        return ACL_GET_ERRCODE_RTS(rtErr);
    }

    ACL_LOG_INFO("successfully execute aclmdlRIExecuteAsync");
    return ACL_SUCCESS;
}

aclError aclmdlRIDestroy(aclmdlRI modelRI)
{
    ACL_PROFILING_REG(acl::AclProfType::AclmdlRIDestroy);
    ACL_STAGES_REG(acl::ACL_STAGE_EXEC, acl::ACL_STAGE_DEFAULT);
    ACL_LOG_INFO("start to execute aclmdlRIDestroy");
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelRI);
    const rtError_t rtErr = rtModelDestroy(static_cast<rtModel_t>(modelRI));
    if (rtErr != RT_ERROR_NONE) {
        ACL_LOG_CALL_ERROR("destroy rtModel failed, runtime result = %d", static_cast<int32_t>(rtErr));
        return ACL_GET_ERRCODE_RTS(rtErr);
    }

    ACL_LOG_INFO("successfully execute aclmdlRIDestroy");
    return ACL_SUCCESS;
}

aclError aclmdlRICaptureBegin(aclrtStream stream, aclmdlRICaptureMode mode)
{
    ACL_LOG_INFO("start to execute aclmdlRICaptureBegin, mode is %d", static_cast<int32_t>(mode));
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(stream);
    const rtError_t rtErr = rtStreamBeginCapture(static_cast<rtStream_t>(stream),
                                                 static_cast<rtStreamCaptureMode>(mode));
    if (rtErr != RT_ERROR_NONE) {
        ACL_LOG_CALL_ERROR("begin capture stream failed, runtime result = %d", static_cast<int32_t>(rtErr));
        return ACL_GET_ERRCODE_RTS(rtErr);
    }

    ACL_LOG_INFO("successfully execute aclmdlRICaptureBegin");
    return ACL_SUCCESS;
}

aclError aclmdlRICaptureGetInfo(aclrtStream stream, aclmdlRICaptureStatus *status, aclmdlRI *modelRI)
{
    ACL_LOG_INFO("start to execute aclmdlRICaptureGetInfo");
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(stream);
    if (status == nullptr && modelRI == nullptr) {
        ACL_LOG_INNER_ERROR("status and modelRI cannot be nullptr at the same time");
        return ACL_ERROR_INVALID_PARAM;
    }
    rtStreamCaptureStatus rtStatus = RT_STREAM_CAPTURE_STATUS_NONE;
    rtModel_t rtModel = nullptr;
    const rtError_t rtErr = rtStreamGetCaptureInfo(static_cast<rtStream_t>(stream), &rtStatus, &rtModel);
    if (rtErr != RT_ERROR_NONE) {
        return ACL_GET_ERRCODE_RTS(rtErr);
    }

    if (status != nullptr) {
        *status = static_cast<aclmdlRICaptureStatus>(static_cast<uint32_t>(rtStatus));
        ACL_LOG_INFO("capture model status is %u", static_cast<uint32_t>(rtStatus));
    }

    if (modelRI != nullptr) {
        *modelRI = static_cast<aclmdlRI>(rtModel);
    }

    ACL_LOG_INFO("successfully execute aclmdlRICaptureGetInfo");
    return ACL_SUCCESS;
}

aclError aclmdlRICaptureEnd(aclrtStream stream, aclmdlRI *modelRI)
{
    ACL_LOG_INFO("start to execute aclmdlRICaptureEnd");
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(stream);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelRI);

    rtModel_t rtModel = nullptr;
    const rtError_t rtErr = rtStreamEndCapture(static_cast<rtStream_t>(stream), &rtModel);
    if (rtErr != RT_ERROR_NONE) {
        ACL_LOG_CALL_ERROR("end capture stream failed, runtime result = %d", static_cast<int32_t>(rtErr));
        return ACL_GET_ERRCODE_RTS(rtErr);
    }
    *modelRI = static_cast<aclmdlRI>(rtModel);

    ACL_LOG_INFO("successfully execute aclmdlRICaptureEnd");
    return ACL_SUCCESS;
}

aclError aclmdlRIDebugPrint(aclmdlRI modelRI)
{
    ACL_LOG_INFO("start to execute aclmdlRIDebugPrint");
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelRI);
    const rtError_t rtErr = rtModelDebugDotPrint(static_cast<rtStream_t>(modelRI));
    if (rtErr != RT_ERROR_NONE) {
        ACL_LOG_CALL_ERROR("print model debug info failed, runtime result = %d", static_cast<int32_t>(rtErr));
        return ACL_GET_ERRCODE_RTS(rtErr);
    }
    ACL_LOG_INFO("successfully execute aclmdlRIDebugPrint");
    return ACL_SUCCESS;
}

aclError aclmdlRICaptureThreadExchangeMode(aclmdlRICaptureMode *mode)
{
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(mode);
    ACL_LOG_INFO("start to execute aclmdlRICaptureThreadExchangeMode, input mode is %d", static_cast<int32_t>(*mode));
    rtStreamCaptureMode rtMode = static_cast<rtStreamCaptureMode>(*mode);
    const rtError_t rtErr = rtThreadExchangeCaptureMode(&rtMode);
    if (rtErr != RT_ERROR_NONE) {
        ACL_LOG_CALL_ERROR("exchange capture mode failed, runtime result = %d", static_cast<int32_t>(rtErr));
        return ACL_GET_ERRCODE_RTS(rtErr);
    }
    *mode = static_cast<aclmdlRICaptureMode>(rtMode);

    ACL_LOG_INFO("successfully execute aclmdlRICaptureThreadExchangeMode, output mode is %d",
                 static_cast<int32_t>(*mode));
    return ACL_SUCCESS;
}

aclError aclmdlRICaptureTaskGrpBegin(aclrtStream stream)
{
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(stream);
    ACL_LOG_INFO("start to execute aclmdlRICaptureTaskGrpBegin");
    const rtError_t rtErr = rtsStreamBeginTaskGrp(static_cast<rtStream_t>(stream));
    if (rtErr != RT_ERROR_NONE) {
        ACL_LOG_CALL_ERROR("begin capture task group failed, runtime result = %d", static_cast<int32_t>(rtErr));
        return ACL_GET_ERRCODE_RTS(rtErr);
    }

    ACL_LOG_INFO("successfully execute aclmdlRICaptureTaskGrpBegin");
    return ACL_SUCCESS;
}

aclError aclmdlRICaptureTaskGrpEnd(aclrtStream stream, aclrtTaskGrp *handle)
{
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(stream);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(handle);
    ACL_LOG_INFO("start to execute aclmdlRICaptureTaskGrpEnd");
    rtTaskGrp_t rtHandle = nullptr;
    const rtError_t rtErr = rtsStreamEndTaskGrp(static_cast<rtStream_t>(stream), &rtHandle);
    if (rtErr != RT_ERROR_NONE) {
        ACL_LOG_CALL_ERROR("end capture task group failed, runtime result = %d", static_cast<int32_t>(rtErr));
        return ACL_GET_ERRCODE_RTS(rtErr);
    }
    *handle = static_cast<aclrtTaskGrp>(rtHandle);

    ACL_LOG_INFO("successfully execute aclmdlRICaptureTaskGrpEnd");
    return ACL_SUCCESS;
}

aclError aclmdlRICaptureTaskUpdateBegin(aclrtStream stream, aclrtTaskGrp handle)
{
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(stream);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(handle);
    ACL_LOG_INFO("start to execute aclmdlRICaptureTaskUpdateBegin");
    const rtError_t rtErr = rtsStreamBeginTaskUpdate(static_cast<rtStream_t>(stream), static_cast<rtTaskGrp_t>(handle));
    if (rtErr != RT_ERROR_NONE) {
        ACL_LOG_CALL_ERROR("begin update capture task group failed, runtime result = %d", static_cast<int32_t>(rtErr));
        return ACL_GET_ERRCODE_RTS(rtErr);
    }

    ACL_LOG_INFO("successfully execute aclmdlRICaptureTaskUpdateBegin");
    return ACL_SUCCESS;
}

aclError aclmdlRICaptureTaskUpdateEnd(aclrtStream stream)
{
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(stream);
    ACL_LOG_INFO("start to execute aclmdlRICaptureTaskUpdateEnd");
    const rtError_t rtErr = rtsStreamEndTaskUpdate(static_cast<rtStream_t>(stream));
    if (rtErr != RT_ERROR_NONE) {
        ACL_LOG_CALL_ERROR("end update capture task group failed, runtime result = %d", static_cast<int32_t>(rtErr));
        return ACL_GET_ERRCODE_RTS(rtErr);
    }

    ACL_LOG_INFO("successfully execute aclmdlRICaptureTaskUpdateEnd");
    return ACL_SUCCESS;
}

aclError aclmdlRIBuildBegin(aclmdlRI *modelRI, uint32_t flag)
{
    ACL_PROFILING_REG(acl::AclProfType::AclmdlRIBuildBegin);
    ACL_LOG_INFO("start to execute aclmdlRIBuildBegin, flag is [%u]", flag);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelRI);

    const rtError_t rtErr = rtsModelCreate(static_cast<rtModel_t*>(modelRI), flag);
    if (rtErr != RT_ERROR_NONE) {
        ACL_LOG_CALL_ERROR("call rtsModelCreate failed, runtime result = %d", static_cast<int32_t>(rtErr));
        return ACL_GET_ERRCODE_RTS(rtErr);
    }

    ACL_LOG_INFO("successfully execute aclmdlRIBuildBegin");
    return ACL_SUCCESS;
}

aclError aclmdlRIBindStream(aclmdlRI modelRI, aclrtStream stream, uint32_t flag)
{
    ACL_PROFILING_REG(acl::AclProfType::AclmdlRIBindStream);
    ACL_LOG_INFO("start to execute aclmdlRIBindStream, flag is [%u].", flag);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelRI);

    const rtError_t rtErr = rtsModelBindStream(static_cast<rtModel_t>(modelRI), static_cast<rtStream_t>(stream), flag);
    if (rtErr != RT_ERROR_NONE) {
        ACL_LOG_CALL_ERROR("call rtsModelBindStream failed, runtime result = %d", static_cast<int32_t>(rtErr));
        return ACL_GET_ERRCODE_RTS(rtErr);
    }

    ACL_LOG_INFO("successfully execute aclmdlRIBindStream");
    return ACL_SUCCESS;
}

aclError aclmdlRIEndTask(aclmdlRI modelRI, aclrtStream stream)
{
    ACL_PROFILING_REG(acl::AclProfType::AclmdlRIEndTask);
    ACL_LOG_INFO("start to execute aclmdlRIEndTask");
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelRI);

    const rtError_t rtErr = rtsEndGraph(static_cast<rtModel_t>(modelRI), static_cast<rtStream_t>(stream));
    if (rtErr != RT_ERROR_NONE) {
        ACL_LOG_CALL_ERROR("call rtsEndGraph failed, runtime result = %d", static_cast<int32_t>(rtErr));
        return ACL_GET_ERRCODE_RTS(rtErr);
    }

    ACL_LOG_INFO("successfully execute aclmdlRIEndTask");
    return ACL_SUCCESS;
}

aclError aclmdlRIBuildEnd(aclmdlRI modelRI, void *reserve)
{
    ACL_PROFILING_REG(acl::AclProfType::AclmdlRIBuildEnd);
    ACL_LOG_INFO("start to execute aclmdlRIBuildEnd");
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelRI);
    if (reserve != nullptr) {
        ACL_LOG_ERROR("[Check][reserve]param must be null.");
        acl::AclErrorLogManager::ReportInputError("EH0002", {"param"}, {"reserve"});
        return ACL_ERROR_INVALID_PARAM;
    }

    const rtError_t rtErr = rtsModelLoadComplete(static_cast<rtModel_t>(modelRI), reserve);
    if (rtErr != RT_ERROR_NONE) {
        ACL_LOG_CALL_ERROR("call rtsModelLoadComplete failed, runtime result = %d", static_cast<int32_t>(rtErr));
        return ACL_GET_ERRCODE_RTS(rtErr);
    }

    ACL_LOG_INFO("successfully execute aclmdlRIBuildEnd");
    return ACL_SUCCESS;
}

aclError aclmdlRIUnbindStream(aclmdlRI modelRI, aclrtStream stream)
{
    ACL_PROFILING_REG(acl::AclProfType::AclmdlRIUnbindStream);
    ACL_LOG_INFO("start to execute aclmdlRIUnbindStream");
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelRI);

    const rtError_t rtErr = rtsModelUnbindStream(static_cast<rtModel_t>(modelRI), static_cast<rtStream_t>(stream));
    if (rtErr != RT_ERROR_NONE) {
        ACL_LOG_CALL_ERROR("call rtsModelUnbindStream failed, runtime result = %d", static_cast<int32_t>(rtErr));
        return ACL_GET_ERRCODE_RTS(rtErr);
    }

    ACL_LOG_INFO("successfully execute aclmdlRIUnbindStream");
    return ACL_SUCCESS;
}

aclError aclmdlRIExecute(aclmdlRI modelRI, int32_t timeout)
{
    ACL_PROFILING_REG(acl::AclProfType::AclmdlRIExecute);
    ACL_LOG_INFO("start to execute aclmdlRIExecute, timeout is [%d] ms.", timeout);
    ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(modelRI);

    const rtError_t rtErr = rtsModelExecute(static_cast<rtModel_t>(modelRI), timeout);
    if (rtErr != RT_ERROR_NONE) {
        ACL_LOG_CALL_ERROR("call rtsModelExecute failed, runtime result = %d", static_cast<int32_t>(rtErr));
        return ACL_GET_ERRCODE_RTS(rtErr);
    }

    ACL_LOG_INFO("successfully execute aclmdlRIExecute");
    return ACL_SUCCESS;
}